我遇到了一个奇怪的问题,我无法解释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
约定应用于partial
和layout
。如果我自己加入下划线,它会回到我预期的行为,即不会在布局名称的前面加_
。
有谁知道为什么会这样?
编辑好吧,不知道我是怎么错过这个...但是文档中提到了这一点。似乎它自2.3.8以来一直存在,或许它在2.3.5(我们运行的是什么)中有所不同?
3.4.3部分布局
一个局部可以使用自己的布局文件,就像一个视图可以使用一个 布局。例如,您可以像这样调用部分:
<%= render“link_area”,:layout => “graybar”%>这将寻找一个 部分命名为_link_area.html.erb并使用布局呈现它 _graybar.html.erb。请注意,partials的布局遵循相同的布局 前导下划线命名为常规部分,并放置在 与其所属部分相同的文件夹(不在主文件夹中) 布局文件夹)。
答案 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的布局遵循相同的布局 前导下划线命名为常规部分,并放置在 与其所属部分相同的文件夹(不在主文件夹中) 布局文件夹)。