Reputation: 44066
For example i have this in my index controller
@users = User.current
this is my User model
scope :current, :conditions => { :active => true }, :order => 'LOWER(first_name), LOWER(last_name) ASC'
Which is basically grabbing all the records and I am not paginating because I am using the jquery datatables table that has a great filter search... the problem I am wanting to achieve is to cache these if possible unless there are new users...which doesnt happen very often
I read about fresh_when but didnt know what could be used here
UPDATE
After following the answer below i dont see CACHE in the log all i see is
Company Load (0.4ms) SELECT `companies`.* FROM `companies` INNER JOIN `positions` ON `companies`.`id` = `positions`.`company_id` WHERE `positions`.`user_id` = 551
Company Load (0.4ms) SELECT `companies`.* FROM `companies` INNER JOIN `positions` ON `companies`.`id` = `positions`.`company_id` WHERE `positions`.`user_id` = 93
Company Load (0.4ms) SELECT `companies`.* FROM `companies` INNER JOIN `positions` ON `companies`.`id` = `positions`.`company_id` WHERE `positions`.`user_id` = 668
Upvotes: 5
Views: 381
Reputation: 49713
class User < ActiveRecord::Base
after_save :clear_cache
def self.current
Rails.cache.fetch("current_users", expires_in: 1.hour) do
User.where(active: true).order("LOWER(first_name), LOWER(last_name) ASC").all
end
end
private
def clear_cache
Rails.cache.delete("current_users")
end
end
Ensure that caching is enabled in config/environments/*.rb:
config.action_controller.perform_caching = true
This is what you want. Read more here:
http://robotmay.com/post/23161612605/everyone-should-be-using-low-level-caching?bda26d48
http://www.tmatthew.net/blog/rails-caching-example
http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html#method-i-fetch
When storing models in the cache, you may run into an odd problem that occurs when the cache is fetched before the models are loaded. Not to worry, this will only happen in development, and there's a fix (application_controller.rb):
before_filter :load_models_if_dev
def load_models_if_dev
if Rails.env == 'development'
User; Post; Comment # whatever other classes that can get cached.
end
end
UPDATE
Notice the .all
in User.where().order().all
. Without that, the value stored in the cache is just an ActiveRecord Relation and not the actual results. Without the .all a query will still have to run. Thanks @Frederick Cheung for bringing that to our attention.
Upvotes: 6