【问题标题】:Change the lookup paths for Rails partial based on model根据模型更改 Rails 部分的查找路径
【发布时间】:2015-08-11 08:51:50
【问题描述】:

我目前有一些这样的模板代码:

render partial: 'reference', locals: { object: object }

Rails 在app/views/application/app/views/controller_name/ 中查找部分_reference.html.erb

但是,此视图位于独立控制器中,与正在渲染的 object 无关,因此它查看对象的视图目录 app/views/object。我不能使用标准的render object 语法并让Rails 自动找出部分路径,因为我不想渲染object/object 部分,而是object/reference 部分。

我怎样才能解决这个问题?

我在想:

  • 使用render object 语法但指定不同的部分名称的某种方式;或
  • 使用不同方法查找部分的辅助函数,使用如下:

    render partial: find_partial('reference', object), locals: { object: object }
    

我的尝试

我试图让第二种方法起作用:

def find_partial(name, object)
  lookup_context.find name, [object.class.model_name.plural, 'application'], true
end

非常接近于做我想做的事,即它找到正确的部分,如果没有,则回退到通用 application/reference。但是,它发现实际的ActionView::Template,而render 需要一个字符串,而不是实际的模板对象。也许有办法取出正确的字符串?还是渲染一个实际的模板?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3


    【解决方案1】:

    你可以在你的模型中重写to_partial_path方法,这个方法被render调用来决定要为这个模型渲染哪个部分路径。

    例如在你的 Model.rb 中

    def to_partial_path
      "references/#{kind}"
    end
    

    参考: http://cookieshq.co.uk/posts/rails-tips-to-partial-path/ http://apidock.com/rails/ActiveModel/Conversion/to_partial_path

    【讨论】:

    • 我喜欢。不幸的是,在其他情况下,我确实使用了常规的render object 方法,而我上面的问题与一个例外有关。我想知道是否有任何方法可以通过调用 render 来传递参数,这将到达 to_partial_path
    • 如果您将变量与渲染render object, var: "value" 一起传递,它们将被传递给to_partial_path 渲染的部分。如果您需要 to_partial_path 中的一些逻辑来确定要渲染的部分,您可以依赖模型属性来避免从视图中传递变量(恕我直言,从架构的角度来看这更好)
    • 嗯,这是一个棘手的问题。在您链接到的站点上,被渲染的部分显然是由域对象的某些质量决定的。在我的用例中,我认为确实是视图决定了所需的部分,但你说得对,我不希望部分本身有逻辑。我在某些地方使用了装饰器模式,我认为在装饰器中覆盖to_partial_path 可能是一个很好的折衷方案。但是仍然需要额外的配置,告诉装饰器它在实例化时是一个引用。
    • 您可以使用prepend_view_path 并在查找视图时将自定义路径添加到rails 使用的列表中。
    【解决方案2】:

    这对我有用:在控制器中,

    before_action :set_lookup_prefixes
    
    def set_lookup_prefixes
      lookup_context.prefixes << "special_folder"
    end
    

    这只是附加它,但您可以在 prefixes 数组中的任何位置注入您的路径。

    警告:我是在 ActionView::LookupContext 类的源代码中发现的,它不是 API 的一部分,可能会发生变化。

    【讨论】:

    • 赞成,但我最终使用了类似lookup_context.prefixes |= Array("special_folder") 的东西,以避免将同一路径多次附加到lookup_context
    【解决方案3】:

    这不是很优雅,但我有一个工作解决方案在视图中调用它:

    render partial: find_partial(:reference, object), locals: { object: object }
    

    find_partial 助手实现为:

    def find_partial(name, object)
      [object.class.model_name.plural, 'application'].each do |dir|
        return "#{dir}/#{name.to_s}" if lookup_context.exists?(name.to_s, dir, true)
      end
      raise "Cannot find partial #{name} for #{object}"
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多