【问题标题】:Rails 6, standalone Jbuilder in a service : partials not loadingRails 6,服务中的独立 Jbuilder:部分未加载
【发布时间】:2020-03-28 01:42:43
【问题描述】:

我认为我可以在 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 partials 不能接受 PORO 作为参数?

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

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

2019 年 4 月 12 日更新

我试过这条线

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

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

我明白了

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

而不是

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

【问题讨论】:

    标签: ruby-on-rails json rails-api ruby-on-rails-6 jbuilder


    【解决方案1】:

    无论出于何种原因,在 Rails 魔术之外,您似乎都必须明确命名 args:

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

    为了避免评估,我会尝试渲染(未经测试)的东西:

    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
    

    【讨论】:

    • 谢谢,但这不起作用,部分在渲染但内容错误。我更新了问题。
    【解决方案2】:

    我认为我可以在 Rails 控制器之外使用 Jbuilder。这 文档是这么说的。

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-29
      • 2020-07-01
      相关资源
      最近更新 更多