作者热门文章
- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
Rails 附带片段缓存和低级缓存。片段缓存的工作原理非常清楚:
Rails will write a new cache entry with a unique key. If the value of updated_at has changed, a new key will be generated. Then Rails will write a new cache to that key, and the old cache written to the old key will never be used again. This is called key-based expiration. Cache fragments will also be expired when the view fragment changes (e.g., the HTML in the view changes). Cache stores like Memcached will automatically delete old cache files.
<% @products.each do |product| %>
<% cache product do %>
<%= render product %>
<% end %>
<% end %>
def get_events
@events = Event.search(params)
time = Benchmark.measure {
event_data = Rails.cache.fetch 'event_data' do
# A TON OF EVENTS TO LOAD ON CALENDAR
@events.collect do |event|
{
title: event.title,
description: event.description || '',
start: event.starttime.iso8601,
end: event.endtime.iso8601,
allDay: event.all_day,
recurring: (event.event_series_id) ? true : false,
backgroundColor: (event.event_category.color || "red"),
borderColor: (event.event_category.color || "red")
}
end
end
}
Rails.logger.info("CALENDAR EVENT LOAD TIME: #{time.real}")
render json: event_data.to_json
end
最佳答案
Rails.cache.fetch 是读写的快捷方式
我们试图对缓存做的是:
value = Rails.cache.read( :some_key )
if value.nil?
expected_value = ...
Rails.cache.write( :some_key, expected_value )
end
:some_key
缓存键,但这次它会存在,我们不需要再次检索该值,我们只需要获取已经缓存的值。
fetch
一次性完成所有操作:
value = Rails.cache.fetch( :some_key ) do
# if :some_key doesn't exist in cache, the result of this block
# is stored into :some_key and gets returned
end
def get_events
# Get the most recent event, this should be a pretty fast query
last_modified = Event.order(:updated_at).last
# Turns a 2018-01-01 01:23:45 datetime into 20180101220000
# We could use to_i or anything else but examples would be less readable
last_modified_str = last_modified.updated_at.utc.to_s(:number)
# And our cache key would be
cache_key = "all_events/#{last_modified_str}"
# Let's check this cache key: if it doesn't exist in our cache store,
# the block will store all events at this cache key, and return the value
all_events = Rails.cache.fetch(cache_key) do
Event.all
end
# do whatever we need to with all_events variable
end
fetch
内堵塞。千万不要每次进入这个方法就触发,不然就失去了所有缓存的兴趣。 get_events
方法的行为举一个例子。假设我们有以下
Events
在您的数据库中:
| ID | Updated_at |
|----|------------------|
| 1 | 2018-01-01 00:00 |
| 2 | 2018-02-02 00:00 |
| 3 | 2018-03-03 00:00 |
get_events
.事件 #3 是最近更新的事件,因此 Rails 将检查缓存键
all_events/20180303000000
.它尚不存在,因此将从 DB 请求所有事件并使用此缓存键存储到缓存中。
get_events
将命中缓存键
all_events/20180303000000
现在存在并包含所有事件。因此,您不会访问数据库,而只是使用缓存中的值。
Event.find(2).touch
| ID | Updated_at |
|----|------------------|
| 1 | 2018-01-01 00:00 |
| 2 | 2018-04-07 19:27 | <--- just updated :)
| 3 | 2018-03-03 00:00 |
get_events
将采用最近的事件(现在#2),因此尝试访问缓存键
all_events/20180407192700
……还不存在!
Rails.cache.fetch
将评估 block ,并将当前状态的所有当前事件放入这个新 key
all_events/20180407192700
.而且您不会得到陈旧的数据。
fetch
内完成事件数据加载。堵塞。
params
过滤事件,缓存将取决于您的参数,因此您需要找到一种方法将参数表示为字符串以将其集成到您的缓存键中。缓存的事件会因一组参数而异。
cache_key
任何 ActiveRecord 对象上的方法作为其缓存键,这很方便并且避免了像我们之前所做的那样繁琐的时间戳格式化。
def get_events
latest_event = Event.search(params).order(:updated_at).last
# text representation of the given params
# Check https://apidock.com/rails/ActiveRecord/Base/cache_key
# for an easy way to define cache_key for an ActiveRecord model instance
cache_key = "filtered_events/#{text_rep_of_params}/#{latest_event.cache_key}"
event_data = Rails.cache.fetch(cache_key) do
events = Event.search(params)
# A TON OF EVENTS TO LOAD ON CALENDAR
events.collect do |event|
{
title: event.title,
description: event.description || '',
start: event.starttime.iso8601,
end: event.endtime.iso8601,
allDay: event.all_day,
recurring: (event.event_series_id) ? true : false,
backgroundColor: (event.event_category.color || "red"),
borderColor: (event.event_category.color || "red")
}
end
end
render json: event_data.to_json
end
关于ruby-on-rails - Rails 低级缓存 : Update cache when ActiveRecord object updated_at changes OR when a new object is added to collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49699795/
我是一名优秀的程序员,十分优秀!