Ruby on Rails: как настроить параметры "найти", чтобы не использовать кеш

В Ruby on Rails вы можете найти записи из базы данных с этим синтаксисом:

<model_name>.find_by_<field_name>()

Примеры: User.find_by_email('[email protected]'), User.find_by_id(1),...

Когда-то, если я не ошибаюсь, я где-то читал, что вы можете явно отключить кеширование для операций "найти", но я не могу вспомнить, как это сделать.

Может кто-нибудь помочь мне запомнить?

Ответ 1

Вы можете использовать ActiveRecord::QueryCache.uncached следующим образом:

User.find_by_email('[email protected]')
User.find_by_email('[email protected]') # Will return cached result

User.uncached do
  User.find_by_email('[email protected]')
  User.find_by_email('[email protected]') # Will query the database again
end

В контроллере он будет выглядеть примерно так:

def show # users#index action
  User.uncached do
    @user = User.find_by_email('[email protected]')
    @another_user = User.find_by_email('[email protected]') # Will query database        
  end

  User.find_by_email('[email protected]') # Will *not* query database, as we're outside of the Users.uncached block
end          

Очевидно, что в модели вам просто нужно сделать:

class User < ActiveRecord::Base
  def self.do_something
    uncached do
      self.find_by_email('[email protected]')
      self.find_by_email('[email protected]') # Will query database
    end
  end
end

User.do_something # Will run both queries

Ответ 2

(Примечание: предполагается, что Rails3, поскольку Rails2 не имеет кэширования по умолчанию.)

Это должно работать так, как вы хотите, чтобы оно было из коробки:

  • Запросы кэшей уничтожаются после каждого действия (http://guides.rubyonrails.org/caching_with_rails.html пункт 1.5)
  • Кроме того, кажется (http://ryandaigle.com/articles/2007/2/7/what-s-new-in-edge-rails-activerecord-explicit-caching), что кеши также уничтожаются по атрибуту/запись обновлений

У вас есть конкретный прецедент, не охваченный конфигурацией по умолчанию?