【发布时间】:2011-02-12 21:15:04
【问题描述】:
我正在开发一个 RoR 应用程序,并且正在编写博客组件。我计划有一个布局文件,它将在博客组件的每个页面上显示数据库中的所有标签。我知道如何创建和使用不同于 application.html.erb 的布局文件,但我不知道如何从数据库中为各种控制器中的每个操作读取标签列表。我不想在每个操作中创建适当的实例变量。解决此问题的适当方法是什么?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3
我正在开发一个 RoR 应用程序,并且正在编写博客组件。我计划有一个布局文件,它将在博客组件的每个页面上显示数据库中的所有标签。我知道如何创建和使用不同于 application.html.erb 的布局文件,但我不知道如何从数据库中为各种控制器中的每个操作读取标签列表。我不想在每个操作中创建适当的实例变量。解决此问题的适当方法是什么?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3
在application_controller 中使用before_filter 来创建实例变量:
before_filter :populate_tags
protected
def populate_tags
@sidebar_tags = Tag.all
end
【讨论】:
read_fragment。您需要缓存该标记位并避免命中,除非该片段已过时;否则,它可能会给整个网站增加一些重大开销。
我建议使用 before_filter,但也将结果缓存在 memcached 中。如果您要对每个请求执行此操作,最好执行以下操作:
class ApplicationController
before_filter :fetch_tags
protected
def fetch_tags
@tags = Rails.cache.fetch('tags', :expires_in => 10.minutes) do
Tag.all
end
end
end
这将确保您的标签被缓存一段时间(例如 10 分钟),因此您只需每 10 分钟执行一次此查询,而不是每次请求。
然后,您可以在侧边栏中显示您的标签,例如,如果您的布局中显示了一个 _sidebar 部分,您可以执行以下操作。
#_sidebar.html.erb
render @tags
【讨论】:
在 ApplicationController 中定义一个私有方法并使用 before_filter 加载它。由于所有的控制器都继承自 ApplicationController,所以它会在每个动作之前执行。
另一个想法是通过辅助方法加载它,但我更喜欢第一个解决方案。
【讨论】: