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

时间:2011-09-06 16:06:04

标签: 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

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

Missing partial layouts/bars with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html]

显然,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约定应用于partiallayout。如果我自己加入下划线,它会回到我预期的行为,即不会在布局名称的前面加_

有谁知道为什么会这样?


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

  

3.4.3部分布局

     

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

     

<%= render“link_area”,:layout => “graybar”%>这将寻找一个   部分命名为_link_area.html.erb并使用布局呈现它   _graybar.html.erb。请注意,partials的布局遵循相同的布局   前导下划线命名为常规部分,并放置在   与其所属部分相同的文件夹(不在主文件夹中)   布局文件夹)。


1 个答案:

答案 0 :(得分: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的布局遵循相同的布局   前导下划线命名为常规部分,并放置在   与其所属部分相同的文件夹(不在主文件夹中)   布局文件夹)。