5

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

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

我想知道是否可以从 inside 的方法中呈现 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

这是我的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是 nil。

关于如何使这两者很好地协同工作,有人有什么好的解决方案吗?

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

对此有什么想法吗?

4

2 回答 2

1

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

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

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

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

class Ticket
  def we_got_what
    "the funk!"
  end
end

为了让你的 Rabl 变得时髦,只需执行以下操作:

object @ticket
 attribute :we_got_what
于 2012-06-16T21:52:56.297 回答
0

现在有一个 rabl wiki 条目描述了这种情况。对于其他到达的人,请在此处查看

解决方案是将装饰器发送给 rabl,而不是从装饰器渲染 rabl。翻转责任使事情变得容易一些。

于 2013-04-15T04:55:56.280 回答