2012-04-13 59 views
5

我在我的Ticket模型的應用程序中有一些相當複雜的JSON響應,我希望我的TicketDecorator成爲構建這些響應的人。使用RABL與Draper渲染to_json

但是,我已經爲我的系統設置了API,並使用RABL來構建這些JSON響應,所以我想重用我已經創建的模板。

我不知道是否有可能從一個方法內作出內部TicketDecorator一個Rabl的模板,這樣的事情:

這裏是我的Rabl的模板tickets/show.json.rabl

object @ticket 

attributes :id, :link, :reported_ago_in_words_with_reporter, 
      :last_updated_in_words_with_updater, :priority_label, :status, 
      :location, :category_list 

node(:attachment_urls) { |ticket| [ asset_path(ticket.first_attachment_url),  asset_path(ticket.second_attachment_url), asset_path(ticket.third_attachment_url) ] } 

node(:comment_count) { |ticket| ticket.comments.count } 

child :recent_comments do 
    extends 'comments/index' 
end 

,這裏是我的TicketDecorator方法:

class TicketDecorator < ApplicationDecorator 
    def as_json 
    h.render(template: "tickets/show", formats: :json) 
    end 
end 

但是,這不起作用,因爲我無法成功設置@ticket,並且我得到了一個錯誤或說:undefined method `first_attachment_url' for nil:NilClass,因爲@ticket爲零。

任何人有什麼好的解決方案,我可以如何讓這兩個很好地結合在一起?

我唯一真正的想法是將模板渲染爲一個字符串並手動使用RABL,但我不知道如何能夠在Draper內部調用render_to_string,因爲它不是視圖幫助器。

對此有何想法?

回答

1

如果是在Rabl中訪問對象的問題,也許this可以幫助你。

同樣在您的自定義節點上,我將直接訪問該對象,而不是依賴塊變量。後者是指IMO處理的集合,像這樣:

collection @tickets 
    attribute :name 
    node(:some_complex_stuff) {|ticket| ticket.vendor.heavy_lifting} 

你也可以考慮這樣的事實,即你可以調用像一個屬性的任何對象的方法,因爲它仍然是紅寶石:)

class Ticket 
    def we_got_what 
    "the funk!" 
    end 
end 

爲了在Rabl的獲得時髦只是做:

object @ticket 
attribute :we_got_what 
0

現在有描述這樣的情況Rabl的維基條目。對於其他人抵達,check it out here

解決的辦法是發送裝飾器到rabl,而不是從裝飾器渲染rabl。翻轉責任使事情變得更容易。