首先,让我说你的方法不是那错误恕我直言。引入一个只是 Page.all 别名的额外方法并不是真正需要的,也不是真正的改进。
但肯定有更好的方法。
我会按如下方式解决这个问题:在ApplicationController 我会添加方法
def get_all_pages
@pages ||= get_all_pages
end
这将确保任何控制器都知道该方法。
然后,如果您确定,每个页面都需要它,您可以在您的ApplicationController 中添加一个before_filter,但一般来说,我更喜欢将它写在控制器本身中。
例如
class IdeasController < ApplicationController
before_action :get_all_pages
... the rest of your controller ...
end
另外,我会将您的页面列表提取到部分中,存储在 app/views/shared/_pages_list.html.erb 或 app/views/pages/_pages_list.html.erb 下,然后在您的 application.html.erb 中调用以呈现部分。
我们调用的方法设置了实例变量@pages,它将在视图中可用,所以你的部分想:
<ul>
<% @pages.each do |page| %>
<li><%= link_to page.name, page_path(page) %></li>
<% end %>
</ul>
最后,为了完整起见,让我回答一下如何使控制器方法在视图中可用。在控制器中写
def get_pages
# ..do something
end
helper_method :get_pages
这将使get_pages 方法在视图中可用,但仅适用于负责加载/呈现该视图的控制器。因此,如果您希望所有视图都使用它,请在 ApplicationController 中定义它。例如。这是我们在定义current_user方法时通常会做的事情。
进一步的改进/替代方案
-
如果您开始获取更多代码,请将与页面列表获取和渲染相关的代码提取到单独的模块中,并将其包含到您的 ApplicationController 中。这使您的ApplicationController 更具可读性。
- 注意:这正是引入
concerns 的目的,因此如果您在 rails 4 上,您可以使用它
Page 是它自己的资源,因此您始终可以创建一个单独的PagesController 并确保它负责呈现列表,并使用 ajax 在需要它的页面上获取。这是一个非常好的解决方案,但也需要更多的工作(矫枉过正?)。但结构非常好。
- 这个问题,页面上有不同的区域,每个区域都应该有自己的控制器-模型-视图,这正是cells gem gem 以非常干净的方式解决的问题。在我链接的页面上有一个非常好的渲染购物车示例,因此您可以随时查看。