在Rails中将数据发送到布局的最佳做法是什么?

时间:2016-02-09 03:03:58

标签: ruby-on-rails

我想知道从控制器到布局有效发送数据的最佳方法是什么。通常,我使用带有yield指令的布局来呈现页面。所以这是我的布局

<!DOCTYPE HTML>
<html lang="en">
<head>
    <%= yield(:title) %>
</head>
<body>
    <%= yield %>
</body>
</html>

和视图文件

<% content_for :title do %>
    <title><%= @title %></title>
<% end %>

<section id="page-body">
   <!-- CONTENT GOES HERE -->
</section>

使用这种方法,我必须在我的控制器中在其视图中需要@title数据的每个方法中定义@title实例变量。

真正的问题是我的标题和其他元数据存储在数据库中,因为视图使用相同的布局文件。所以我认为像标题和关键字这样的数据不应该过于频繁地加载(至少不是在每个方法中),并且不应该在每个视图中声明content_for。

那么布局是否可以直接从控制器访问这些数据?不使用content_for

谢谢

1 个答案:

答案 0 :(得分:1)

有两种方法:

  1. ApplicationController
  2. 中设置值
  3. 在init
  4. 设置“默认”值

    <强>控制器

    如果您是ApplicationController来自ApplicationController的控制器,则始终会调用before_action。这意味着,如果您希望/需要设置数据库中的值,可以使用#app/controllers/application_controller.rb class ApplicationController < ActionController::Base before_action :set_meta private def set_meta @title ||= ... end end 回调来执行此操作:

    #app/views/layouts/application.html.erb
    <title><%= @title || "Fallback" %></title>
    

    然后按如下方式填充布局:

    layout

    -

    <强>默认值

    如果您希望使用defaults填充网站范围内的数据,则最好使用初始化程序设置constants / #config/initializers/meta.rb META = { title: Option.find_by name: "title" keywords: Option.find_by name: "keywords" }

    #config/settings.yml
    site:
      title:    <%= Option.find_by name: "title" %>
      keywords: <%= Option.find_by name: "keywords" %>
    
    #app/views/layouts/application.html.erb
    <title><%= yield(:title) || Settings.title %></title>
    

    我们使用其中一个subclassing宝石来填充这些数据:

    def modify_duplicates_ordered(original):
        result = []
        for val in original:
            while val in result:
                    val += 0.0001
            result.append(val)