使用RABL和Draper渲染to_json

The*_*hop 5 ruby ruby-on-rails decorator draper rabl

我的Ticket模型应用程序中有一些相当复杂的JSON响应,我希望我TicketDecorator能够构建这些响应.

但是,我已经为我的系统设置了API并使用RABL来构建那些JSON响应,所以我想重用我已经创建的模板.

我想知道是否可以在一个方法内部渲染RABL模板TicketDecorator,如下所示:

这是我的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
Run Code Online (Sandbox Code Playgroud)

这是我的TicketDecorator方法:

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

但是,这不起作用,因为我不能成功设置@ticket,我得到一个错误说: undefined method `first_attachment_url' for nil:NilClass因为@ticket是零.

任何人都有任何好的解决方案,我可以如何使这两个很好地一起工作?

我唯一真正的想法是将模板渲染为字符串并手动使用RABL,但我不确定我是如何调用render_to_stringDraper内部的,因为它不是视图助手.

有什么想法吗?

dab*_*bai 1

如果是访问 Rabl 中的对象的问题,也许对您有帮助。

另外,在您的自定义节点上,我将直接访问该对象,而不是依赖块变量。后者是用于处理集合的,如下所示:

collection @tickets
  attribute :name
  node(:some_complex_stuff) {|ticket| ticket.vendor.heavy_lifting}
Run Code Online (Sandbox Code Playgroud)

您还可以研究这样一个事实,即您可以调用任何对象方法(如属性),因为它仍然是 Ruby :)

class Ticket
  def we_got_what
    "the funk!"
  end
end
Run Code Online (Sandbox Code Playgroud)

为了让你的 Rabl 变得时髦,只需这样做:

object @ticket
 attribute :we_got_what
Run Code Online (Sandbox Code Playgroud)