Is there a way to cache the .all call?

caching, ruby, ruby-on-rails, ruby-on-rails-3

Solution

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.

Problem

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 ```

Original source