在模型中渲染json的Rails

时间:2012-02-10 19:57:12

标签: ruby-on-rails json ruby-on-rails-3.2 jbuilder

在我们的rails 3.2 app中,我们使用Jbuilder来渲染我们的json响应(这里没什么特别的)。 json视图可以这么简单:

_model_name.json.jbuilder

json.extract!(page, :id, :name, :url_name)

我们经常需要返回一个深度嵌套的json对象,而Jbuilder partials对此非常有用:

_page.json.jbuilder

json.extract!(page, :id, :name, :url_name)
json.page_images (page_images) do |json, page_image|
    json.partial! page_image
end

最后一个例子将检索页面,嵌套的page_images,json表示......再没什么特别的。

通常,单个partial会调用另一个,并且可能返回嵌套的json对象2或3级深。

问题

就像我上面提到的,我们使用Jbuilder partials将多个partials快速链接在一起,形成一个深度嵌套的json对象。我们还需要构建这些完全相同的嵌套对象作为哈希(而不是json)并使它们可用于模型。

使用.attributes获取Jbuilder对象输出哈希很简单!方法,但是我们有一些严重的困难,让Jbuilder可以访问模型中的视图部分。

查看Jbuilder源代码,看起来JbuilderTemplate类需要访问控制器上下文才能使一切正常工作。

我们可能会尝试这样的事情:

class SomeClass

  def initialize pages
    @pages = pages
    @context = ActionController::Base.new
  end

  def to_hash
     builder = JbuilderTemplate.new(@context)
     builder.pages(@pages) do |json, page|
        json.partial! page
     end
     builder.attributes!
  end
end

上面的示例显然是不正确的,但它说明了需要做什么。我只是不确定如何从模型中初始化控制器,然后传递控制器上下文。

我们关注的一些主要内容:

任何人都可以帮助我们指出正确的方向吗?

4 个答案:

答案 0 :(得分:2)

我很确定你在这里走在正确的轨道上。如果直接在初始化程序中传递块,您应该能够调用json.array!并正常构建部分。

def to_hash
  builder = JbuilderTemplate.new(@context) do |json|
    json.array! @pages, partial: 'path/to/partial'
  end
  builder.attributes!
end

答案 1 :(得分:1)

无法找到解决方案。我们回过头来使用as_json来配置我们的模型json输出。

答案 2 :(得分:0)

我使用ActiveModel :: Serializer来做同样的事情。您可以在模型中或之前渲染json - 我们这样做是为了预先填充缓存。

这样做的语法最初并不明显,所以我在这里发帖:

ItemSerializer.new(item).to_json

答案 3 :(得分:0)

如果你真的需要这个功能,我可以给你看一些垫片:

c = ActionController::Base.new
c.instance_variable_set '@item', Item.find(5)
JSON.parse c.render_to_string('items/show')