我对rails非常陌生,所以如果我使用错误的术语,我会道歉。
我有一个模型Menuitem,我想在布局中显示内容。如何将实例变量传递到布局?
我正在寻找某种布局助手,但我无法找到任何东西。我还在考虑在应用程序控制器中定义实例变量以在布局中访问它,这会起作用吗?如果是这样,最好的方法是什么?
谢谢!
答案 0 :(得分:15)
将变量从视图传递到父布局的常用方法是使用content_for
方法。 (这个答案是我在this question张贴的类似答案的副本+粘贴)
普通视图内容会自动呈现到yield
调用中,而布局中没有参数。但您也可以使用带有符号参数的yield
并使用content_for
从视图中指定该内容,将其他占位符内容放入其中。
app/views/layouts/posts_layout.html.erb
<html>
<head>
<title>My awesome site</title>
</head>
<body>
<div id="someMenuStructureHere">
<%= yield(:menu_items) %> <!-- display content passed from view for menu_items -->
</div>
<%= yield %> <!-- display main view content -->
</body>
</html>
app/views/posts/index.html.erb
<%= content_for :menu_items, some_helper_to_generate_menu %>
<h1>Here is you page content</h1>
答案 1 :(得分:3)
我会注意到两件事。首先,您可能不希望每次在应用程序中呈现任何页面时都执行此查询。你肯定想要缓存你的MenuItems。其次,在MenuItems类上放置一个方便方法来缓存这个值可能会有所帮助。所以,如果我定义一个方法
def MenuItem.all_for_menu
@@all_for_menu ||= MenuItem.find(:all) #returns value if exists, or initializes it
end
我可以在布局中调用MenuItem.all_for_menu并获取所有菜单项。当你添加一个新的或编辑一个时,你必须使它无效。
另一种缓存方法是将数据放入局部并使用标准缓存调用缓存该片段:
<% cache(:controller => "menu_items",
:action => "list",
:action_suffix => "all_menu_items") do %>
<%= render :partial => "menu", :collection => MenuItem.all_for_menu %>
<% end %>
然后您可以通过调用:
使该片段到期expire_fragment(:controller => "menu_items", :action => "list", :action_suffix => "all_menu_items")
答案 2 :(得分:0)
控制器中定义的任何实例变量都可以在视图中自动神奇地使用。如果您希望布局中的所有操作都有实例变量,您可能需要考虑在before_filter中定义实例变量或将其封装在控制器方法中,并使用helper_method使其在您的视图中可访问。
答案 3 :(得分:-2)
这实际上取决于你想对model
做些什么。我只是猜测,你告诉我你需要什么不同,以便更好地了解如何做到这一点。仅当您的MenuItem模型具有名为name
的字段时,此代码才有效。
在控制器中:
# Use whatever action you are currently displaying
def index
@menu_items = MenuItem.all
end
在index.html.erb
视图文件中:
<ul id="menu">
<% @menu_items.each do |menu_item| %>
<%= h menu_item.name %>
<% end %>
</ul>
显然,如果这是一个真正的菜单,那里也会有超链接:)
答案 4 :(得分:-2)
items_controller.rb
(或其他)
def show
@menu_item = MenuItem.find(params[:id])
end
在视图中show.html.erb
:
<%= @menu_item.name %>