Rails 3: обратный вызов, когда определенный объект извлекается из базы данных (Mongo Mapper)

Мне нужно что-то, что может запускать метод, когда объект извлекается из базы данных и вызывается. Так, например, допустим, у меня есть класс Apple. Я делаю запрос:

Apple.where(:name => "Delicious").first

который возвращает

#<Apple id: 2, blah, blah, blah>

Мне нужен способ (обратный вызов или другой) для вызова метода, чтобы я мог отслеживать, сколько раз элемент извлекался из базы данных. Может ли кто-нибудь предложить способ сделать это? Я использую MongoDB с MongoMapper.


person Red    schedule 23.01.2012    source источник


Ответы (3)


Существует обратный вызов after_find, который вызывается после загрузки объекта из базы данных. . Так:

after_find :update_found_count

def found_times
  increment!(:found_count)
end
person Shadwell    schedule 23.01.2012
comment
К сожалению, это решение не работает с Mongo Mapper, можете ли вы дать мне решение для этого? - person Red; 11.02.2012
comment
Нет, извините, я не знаю конкретного решения для этого. Однако может быть более плодотворным задать другой вопрос, чем редактировать этот вопрос и потенциально делать ответы, которые люди уже дали вам, неактуальными. - person Shadwell; 11.02.2012

Предположим, что ваша модель имеет атрибут с именем access_count, вы можете переопределить initialize, чтобы сделать что-то вроде этого:

Обновление: ответ Shadwell лучше; направляйте свои голоса таким образом. Оставив ниже, на случай, если это будет кому-то полезно.

class Apple < ActiveRecord::Base
  def initialize *args
    super

    incr_access_count
  end

  private
  def incr_access_count
    update_attribute :access_count => access_count + 1 unless new_record?
  end
end

Это довольно наивно, но в любом случае предсказуемо. Мне кажется, что сделать это явно в вашем контроллере было бы гораздо разумнее. Обновление записи каждый раз, когда она извлекается из базы данных, имеет значительный запах, и трудно представить сценарий, в котором количество раз, когда она была извлечена, было бы полезной метрикой.

person Jordan Running    schedule 23.01.2012

Новая фабрика для переопределения фабрики по умолчанию была бы правильным способом сделать это.

Пример:

class Apple < ActiveRecord::Base
  # ...
  def self.delicious
    # increase count or other complex operations here
    where(:name => "Delicious").first
  end
  # ...
end

В этом случае where является фабрикой по умолчанию.

При этом вы можете просто позвонить Apple.delicious и покончить с этим.

person Swanand    schedule 23.01.2012
comment
Я бы возражал против использования здесь .first, так как это вызывает запрос. Но я думаю, что это выходит за рамки этого вопроса. - person Swanand; 23.01.2012