Rails: запуск кода перед извлечением модели ActiveRecord - PullRequest
0 голосов
/ 21 марта 2012

Есть ли способ запустить код ДО поиска модели? Я знаю о обратном вызове after_find , но мне нужно запустить его раньше. Я также хотел бы, чтобы он выполнял только ОДИН РАЗ за поиск, независимо от количества возвращенных записей. Глядя на источник RoR, кажется, что запрос фактически выполняется в exec_queries (или to_a ) в ActiveRecord :: Relation . Делать / Должен ли я переопределить этот метод, чтобы добавить этот хук?

И на всякий случай я все делаю неправильно, поэтому я спрашиваю, у меня есть внешний REST API, который я использую для извлечения данных, но он слишком медленный для извлечения после каждой перезагрузки страницы. Первоначально я использовал memcached, но я решил, что могу просто использовать ActiveRecord для кэширования данных в базе данных, чтобы я мог легко запрашивать данные и, возможно, объединять их с аналогичными данными из других API REST. Я хотел бы подключить функцию обратного вызова, которая по истечении определенного времени ожидания перезагрузит данные из REST перед возвратом результатов ActiveRecord.

По сути, я ищу лучший способ централизовать обновление моей базы данных из другого источника (REST) ​​вместо того, чтобы загромождать мои контроллеры или переопределять все используемые мной средства доступа к моделям (есть ли способ переопределить их все легко?). Возможно, лучшее решение лежит здесь.

Появляются все встроенные методы, такие как all, find, first и last call apply_finder_options (а затем где ), но динамически созданные искатели (find_by_name и т. Д.) вызовите find_dynamic_match , который в конечном итоге вызывает , где . Это то, что привело меня к методу to_a в отношении, так как он является общим и вызывается при фактическом выполнении запроса, а не только при построении отношения перед выполнением запроса. Однако этот низкий уровень в Rails делает меня неудобным.

Кажется, моя проблема не должна быть необычной, поэтому, возможно, мой подход неверен?

К вашему сведению, я новичок в рельсах и рубине. Спасибо!

1 Ответ

1 голос
/ 21 марта 2012

Я бы настоятельно рекомендовал не использовать низкоуровневый хук вместо явной проверки кэша.ActiveRecord имеет свой собственный механизм кэширования, но если это не делает его для вас, и вам нужно создать свой собственный - используйте его явно перед использованием средств поиска ActiveRecord.Подобные зацепки могут очень запутанно определять, что происходит и почему, и это не рекомендуемая практика.Вот пример использования модели прокси:

class CacheProxy
  attr_accessor :klass
  def initialize(klass)
    @klass = klass
  end

  def method_missing(method_id, *arguments, &block)
    reload_if_necessary
    klass.send(method_id, *arguments, &block)
  end

  private
  def reload_if_necessary
    return unless needs_reload?
    # perform reload
  end

  def needs_reload?
    # determine if we need to reload the cache
  end
end

class ActiveRecord::Base
  def self.proxy
    CacheProxy.new(self)
  end
end

Теперь вы даже можете сделать MyModel.proxy.find_by_first_name_and_last_name('John', 'Doe')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...