在我们的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
上面的示例显然是不正确的,但它说明了需要做什么。我只是不确定如何从模型中初始化控制器,然后传递控制器上下文。
我们关注的一些主要内容:
任何人都可以帮助我们指出正确的方向吗?
答案 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')