我想知道从控制器到布局有效发送数据的最佳方法是什么。通常,我使用带有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
谢谢
答案 0 :(得分:1)
有两种方法:
ApplicationController
<强>控制器强>
如果您是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)