Rails 6,服务中的独立Jbuilder:部分未加载



我想我可以在Rails控制器之外使用Jbuilder。文件是这样说的。

我编写了这个模块,以包含在服务对象中。它集成在Rails 6 api应用程序中,但不是从ActiveRecord继承的。

module JsonGenerator
def to_json
template = File.read("#{::Rails.root}/path/to/template.json.jbuilder")
Jbuilder.new { |json| eval template }.target!
end
end
class Converter::Album
include JsonGenerator
end

如果我不使用任何部分,这是有效的。但是当我这样做时,使用这样的语法:

json.artists artists do |artist|
json.partial! 'artist', artist: artist
end

我收到此错误:

Failure/Error: eval template
TypeError:
{:artist=>#<Converter::Artist:0x00007fd0d1a99dc8 @name="Bob">} is not a symbol nor a string

问题似乎是 Jbuilder 部分不能接受 PORO 作为论据?

无论如何我都不想使用eval,但这是我找到的加载不在views文件夹中的模板的唯一方法。

如果我将所有模板直接复制粘贴为Jbuilder.new方法的参数,则会出现相同的错误。

更新 04/12/2019

我试过这条线

json.partial! partial: 'artist', locals: { artist: artist }

即使它加载了部分,它生成的数据也是错误的。

我明白这个

"artists" => [{"partial!"=>{"locals"=>{"name"=>"Bob", "instrument"=>"piano"}, "partial"=>"artist"}}]

而不是

"artists" => [{"name"=>"Bob", "instrument"=>"piano"}]

无论出于何种原因,当外部轨道魔法时,您似乎必须明确命名参数:

json.partial! partial: 'artist', locals: { artist: artist }

为了避免 eval,我会尝试一些渲染的东西(未经测试(:

def to_json
ApplicationController.render(template: 'albums/show.json.jbuilder', assigns: { album: self }, formats: [:json], handlers: [:builder])
end

或者使用新的渲染器:

def to_json
renderer = ApplicationController.new
renderer.render('albums/show.json.jbuilder', locals: { album: self }, formats: [:json], handlers: [:builder])
end

我想我可以在Rails控制器之外使用Jbuilder。这 文件是这样说的。

可以,但并非所有可以在视图上下文中使用的方法都可用。 这是因为它们实际上是两个不同的对象,Jbuilder 和 JbuilderTemplate,后者接受context参数,它是ActionView::Base(或其子类(的实例。

您在视图上下文之外使用的对象是Jbuilder的实例,并且没有#partial!方法,这就是为什么您在返回的 JSON 中有"partial!"键的原因——它的处理方式与任何其他键没有任何不同。

据我所知,完成你想做的事情的唯一(简单(方法是使用ActionController::Renderer(正如@Mene所说(。

ApplicationController.render 'path/to/template.jbuilder', locals: {...}, assigns: {...}

相关内容

  • 没有找到相关文章

最新更新