Rails 3 vs 2.3.5使用:partial和:layout来渲染奇数

Kri*_* PD 9 ruby-on-rails ruby-on-rails-3

我遇到了一个奇怪的问题,我无法解释Rails 3和渲染部分布局(来自控制器).我希望有人可以提供一些有关正在发生的事情的见解.

首先,我们将此控制器称为"传统"控制器.它已经存在了很长时间,并且做了很多错事,但我现在不打算重构它,所以我试图找到合作方式来处理我们拥有的东西.

这个new动作是这样的(在BarsController)

def new
  if something
    render :partial => "foo", :layout => "bars"
  elsif something_else
    render :partial => "foo2", :layout => "bars"
  elsif something_else_else
    render :partial => "foo3", :layout => "bars"
  else
    render :partial => "foo4", :layout => "bars"
end
Run Code Online (Sandbox Code Playgroud)

现在,在Rails 2.3.5中,这很好用.它会在适当的布局中呈现适当的部分 - 我意识到布局选项在这里是多余的,因为无论如何都会默认为条形布局.当我们升级到Rails 3.0.x时,我们开始收到如下错误:

Missing partial layouts/bars with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html]
Run Code Online (Sandbox Code Playgroud)

很明显,layouts/bars.html.erb文件一直存在,所以我无法理解.我能够渲染:layout => false,但那当然不会起作用.最终我发现,如果我执行以下任一操作,它会起作用:

1)重命名我的布局_bars.html.erb而不是bars.html.erb和:

render :partial => 'foo2', :layout => 'bars'

2)保持我的布局bars.html.erb(我想要的)和:

render '_foo2' # :partial option is redundant here anyway


似乎通过使用:partial选项而不是字符串作为第一个参数导致rails将_name.html.erb约定应用于partialAND和layout.如果我自己输入下划线,它会回到我预期的行为,即不会_在布局名称的前面加上前缀.

有谁知道为什么会这样?


编辑好吧,不知道我是怎么错过这个...但是文档中提到了这一点.似乎它自2.3.8以来一直存在,也许它在2.3.5(我们运行的是什么)中有所不同?

3.4.3部分布局

部分可以使用自己的布局文件,就像视图可以使用布局一样.例如,您可以像这样调用部分:

<%= render"link_area",:layout =>"graybar"%>这将查找名为_link_area.html.erb的部分并使用布局_graybar.html.erb进行渲染.请注意,partials的布局遵循与常规partials相同的前导下划线命名,并且与它们所属的部分放在同一文件夹中(不在master layouts文件夹中).


Kri*_* PD 15

以下是基于我上面编辑过的问题的答案:

从Rails 2.3.8开始,看起来好像渲染部分的默认行为render :partial => 'foo', :layout => 'bars'是期望"部分布局"文件以及部分视图文件.在这种情况下,它会期望

app/views/_foo.html.erb 以及 app/views/layouts/_bars.html.erb

对于从Rails 2.3.5升级遇到此问题的任何人,我发现这里的解决方案影响最小:

render '_foo', :layout => 'bars'

此解决方案不会假设您呈现部分,因此不期望部分布局.另一种选择是将您的布局复制到

app/views/layouts/_bars.html.erb

和使用

render :partial => 'foo', :layouts => 'bars'

但这会导致一些代码重复.

铁路2.3.8+ DOC关于此:

3.4.3部分布局

部分可以使用自己的布局文件,就像视图可以使用布局一样.例如,您可以像这样调用部分:

<%= render"link_area",:layout =>"graybar"%>这将查找名为_link_area.html.erb的部分并使用布局_graybar.html.erb进行渲染.请注意,partials的布局遵循与常规partials相同的前导下划线命名,并且与它们所属的部分放在同一文件夹中(不在master layouts文件夹中).