Rails 3和局部布局

Rails 3 and partials layouts

我正在尝试为每个对象呈现相同格式的不同对象的集合。我想保持它为DRY,所以我想使用局部布局和局部布局。

编辑-简要说明:我需要的不是在所有发布页面上显示通用项目,而是在每个项目上显示通用属性/字段。这就是为什么我需要局部布局的原因部分布局,而不是页面布局。

我有一个不同的对象集合:

1
2
3
@publications = Publications.all
# Publication is the parent class
# @publications = [ImagePost, VideoPost, TextPost, ...]

我想呈现列表中的所有出版物。每个出版物都有一些共同的属性:作者,日期,...我想将此属性放在局部布局中。

因此,在我看来,要渲染集合,我要做:

1
<%= render :partial => 'publications', :locals => {:publications => @publications} %>

在第一级局部views/publications/_publications.html.erb中,我在项目上循环并尝试使用共同的局部布局以其局部方式渲染每个项目:

1
2
3
4
5
6
<ul class='publications_list'>
  <% publications.each do |p| %>
    <%= render p, :layout => 'publications/publication_layout' %>
  <% end %>

</ul>

局部布局views/publications/_publication_layout.html.erb

1
2
3
4
5
6
7
<li>

  <%= link_to publication.title, publication %>
  ... Other common properties that I want to display on each item, independently of its type ...
  <p><%= yield %></p>

</li>

最后对于每种对象类型,我都有一个部分代码(例如image_posts/_image_post.html.erb等),其中包含可以正确显示每个代码的代码。

我的问题:我无法以通用的局部布局publication_layout呈现每个出版物。该布局仅被rails忽略。正确渲染了每个项目,但没有包含通用属性和
<MMKG1>
标签的布局。

关于为什么我的局部布局会被忽略的任何建议吗?


答案和解决方法

感谢@MarkGuk在doc中发现了这一行:

Also note that explicitly specifying :partial is required when passing
additional options such as :layout.

因此,不可能简单地在每个项目的相同局部内渲染多态集合。

解决方法1:我首先尝试为每个项目计算部分路径,为方便起见将其存储在模型中,然后使用良好的布局将每个项目呈现为良好的部分。但我意识到这种方法无法引用布局内的对象publication ...

1
2
3
4
5
6
7
<ul class='publications_list'>
  <% publications.each do |p| %>
    <% # p.partial = p.class.to_s.underscore.pluralize +'/'+ p.class.to_s.underscore %>
    <%= render :partial => p.partial, :object => p, :as => :publication, :layout => 'publications/publication_layout' %>
  <% end %>

</ul>

解决方法2:
最后,我使用了嵌套的局部函数。

1
2
3
4
5
6
<ul class='publications_list'>
  <% publications.each do |p| %>
    <%= render :partial => 'publications/publication_layout', :object => p, :as => :publication %>
  <% end %>

</ul>

,并在布局内将yield替换为render publication


查看对问题的评论和作者的带标记的答案。

文档

作者的回答


我想知道嵌套布局在这里是否可以为您提供更好的服务。该指南应为您指明正确的方向,我发现开始工作很容易,但是作为一个开始:

views/layouts/application.html.erb中,将yield更改为:

1
<%= content_for?(:publication_content) ? yield(:publication_content) : yield %>

消除部分views/publications/_publication.html.erb,而是创建嵌套布局views/layouts/publication.html.erb

1
2
3
4
5
6
<% content_for :content do %>
    # Put common items here
    <%= content_for?(:content) ? yield(:content) : yield %> # this is for specifics
<% end %>

<%= render :template => 'layouts/application' %>

然后,根据您的设置的其余部分,可以将特定的布局进一步嵌套或在视图中用其他标签指定。