【问题标题】:Why does Rails make layout selection a controller concern instead of a view concern? Can I choose a layout from a view?为什么 Rails 让布局选择成为控制器关注点而不是视图关注点?我可以从视图中选择布局吗?
【发布时间】:2025-12-14 04:55:01
【问题描述】:

也许它有技术/实施原因,但在我看来,“布局”几乎是视图层的一部分,但 Rails 似乎只允许在控制器级别指定布局。

我的控制器不应该关心布局......模板应该。有没有办法从 .erb 文件中指定要使用的布局?

类似:

<%= with_layout :news_feed do %>

  <p>
    My markup in here.
  </p>

<% end %>

或您能想到的任何其他实现...但文档似乎仅从控制器的角度引用布局。

也许实现 with_layout 助手不会太难。

编辑 |我找到了我正在寻找的东西:

<% render :layout => "some_layout" do %>
  <p>
    My markup here
  </p>
<% end %>

现在假设您的 ActionController 具有:

class ApplicationController < ActionController::Base
  layout nil

然后每个模板可以使用这种方法选择自己的布局。

如果您在 app/layouts 中放置一个布局,其名称与控制器匹配,则将使用该布局,因此您不必严格指定它们是否都相同。无论哪种方式,编写模板的家伙现在都可以完全控制它,而不是编写控制器的家伙:)

【问题讨论】:

    标签: ruby-on-rails layout


    【解决方案1】:

    我做了一些研究,但没有找到与您正在寻找的类似的解决方案。

    我认为这可能与指定默认布局以外的布局可以通过在app/views/layouts 下命名文件your_controllers_name.html.erb 来完成这一事实有关。如果特定控制器始终使用相同的布局,这可以从控制器中删除任何逻辑。也许这就是你要找的东西?如果您没有与布局匹配的控制器名称,则将使用默认的 application.html.erb

    如果您需要有条件地呈现不同的布局,则需要在控制器中做出该决定。否则,您会将决策逻辑下推到您的视图中。您的视图不必决定它需要什么布局,因为控制器可以做出决定并设置视图所需的任何必要数据。

    【讨论】:

    • 谢谢,是的,我从文档中得到了这个,但这看起来真的有点奇怪。我们的团队非常明确地分为设计师和开发人员,设计师永远不必接触我们的控制器。也许我们会回退到使用包含前端人员包含的顶部和底部部分的空布局。或者,也许我会研究一个允许 with_layout 块的解决方案。我们有四个或五个“标准”布局,它们不一定与任何特定的控制器链接……它只取决于页面内容。
    • @d11wtq - 我知道你从哪里来,虽然你的设计师仍然不需要触摸控制器代码,对吧?他们可以在 layouts 目录中创建布局,然后如果需要,开发人员可以添加任何条件代码。一般来说,尽管您可能在 95% 的时间内都可以摆脱控制器命名约定方案。
    • @d11wtq,您发布的代码块是否解决了您的问题?如果是这样,您确实应该将其设为答案,以便将其标记为答案。
    【解决方案2】:

    一些陈述:

    布局是关于渲染。
    布局只能调用一次。
    视图 - 是*(最后)渲染级别。
    控制器 - 是第一级渲染层。

    所以我可以说唯一可以设置布局的地方是控制器。如果我们可以从视图中设置布局,那么嵌套布局就会出现问题,因为每个视图(部分视图)都会调用自己的布局。

    控制器如何设置布局简单明了。如果我们从其子级设置父级视图,则不清楚且混乱。

    你在说什么 - 是屈服 (content_for) 和部分 (render :partial)。这是很棒的工具,而且效果很好。

    【讨论】:

    • 好吧,我不同意这是控制器的问题。这可能是最简单的解决方案,但布局基本上是模板的一部分;它与控制器无关。我知道我们设置它的位置是在控制器中……但这是 Rails 的东西,而不是 MVC 的东西。
    • 另外,关于嵌套布局,很有可能有子布局,比如在内容周围绘制框等等......它基本上只是在说:“我即将生成一些内容,我希望这个文件呈现该内容”。该文件是否包含 标签和其他*内容既不存在也不存在;)
    • @d11wtq, for things like drawing boxes around content etc 这正是 partials 所做的。您根本不需要子布局。布局 - 是没有任何子布局的单个文件。子布局是部分。控制器关注的是选择一个布局作为渲染的起点。实际上控制器做什么 - 正在渲染。所以选择布局是控制器的工作。