这是一个普遍的问题,但为了解决这个问题,我们来讨论一个具体的例子。假设您的应用程序经常使用包含世界上所有国家/地区列表的表单。这些国家/地区存储在数据库的countries
表中,但此表很少更新,只能通过seeds.rb文件进行更新。
为了能够在每个请求中节省一点时间,我通常按如下方式处理这类事情:
module ApplicationHelper
def self.get_countries
countries = Country.order("name asc").all.collect{|country| [country.name, country.name]}
countries.unshift(["",""])
countries
end
# In production mode (cache_classes = true) this is executed only once, and
# will remain cached until you restart your application server
@@COUNTRIES = ApplicationHelper.get_countries
# This would be called from various views
def countries_for_select(country)
selected = country.name unless country.nil?
options_for_select(@@COUNTRIES, selected)
end
end
这是一种合理的方法吗?
请不要建议不存储数据库中的国家/地区列表。我知道还有其他方法可以管理国家/地区列表。我并不是真的关心国家 - 这是我能想到的最容易理解的例子来说明这个一般性的问题。
答案 0 :(得分:0)
我不确定“非渲染数据”是什么意思。使用您的方法,表单视图仍然需要遍历所有国家/地区,并为每个国家/地区呈现选项。
<select id="user_country" name="user[country]">
<option value="US">United States</option>
<option value="CA">Canada</option>
<option value="ET">Etcetera</option>
但是,如果将select包装在片段缓存中,那么第一次在最后一次部署后呈现表单时,将呈现选择选项,然后将其缓存到/ tmp / cache中的单独文件中。然后在每次后续加载表单时,rails将使用该缓存文件,就像它是部分文件一样并插入到表单中。
<% form_for @user do |form| %>
<% cache('user_countries_selector') do %>
<% form.select :country, Country.order("name asc").all.collect{|country [country.name, country.name]}
<% end %>
<% etc, etc, etc %>
<% end %>
虽然在实践中,我可能会将Country.order...
代码移出到辅助方法。使用此方法完全不需要将国家/地区列表缓存到@@ COUNTRIES。
如果您需要以其他形式呈现国家/地区,则应将不同的密钥传递给cache()
,因为呈现的选择标记的ID和名称将是特定于表单的。