Как пропустить обратные вызовы ActiveRecord?

Возможный дубликат:
Как я могу избежать запуска обратных вызовов ActiveRecord?

У меня есть такая модель

class Vote < ActiveRecord::Base  
    after_save :add_points_to_user

    .....
end

Можно ли как-то заставить модель пропустить вызов add_points_to_user когда сохранено? Возможно что-то вроде ActiveRecord#delete против ActiveRecord#destroy?

4 ответа

Решение

Для Rails 2, но не для Rails 3 вы можете использовать это:

object.send(:create_without_callbacks)
object.send(:update_without_callbacks)

Для Rails 3 ActiveSupport::Callbacks дает вам необходимый контроль. Я просто столкнулся с той же проблемой в сценарии интеграции данных, где обычно нужно было отбрасывать обратные вызовы. Вы можете выполнить reset_callbacks в массовом порядке или использовать skip_callback для разумного отключения, например:

Vote.skip_callback(:save, :after, :add_points_to_user)

.. после чего вы можете работать с экземплярами голосования с помощью:add_points_to_user запрещена

Следующее относится к рельсам 2, рельсам 3 и рельсам 4:

http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html

Он предоставляет список методов, которые пропускают обратные вызовы, объясняя, почему опасно использовать их без тщательного рассмотрения. Перепечатано здесь в соответствии с положениями лицензии Creative Commons Attribution-Share Alike 3.0.

12 Пропуск обратных вызовов

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

  • декремент
  • decrement_counter
  • удалять
  • удалить все
  • find_by_sql
  • приращение
  • increment_counter
  • тумблер
  • потрогать
  • update_column
  • обновить все
  • update_counters

Это пропустит ваши проверки:

vote.save(:validate => false)

больше информации здесь

Чтобы пропустить ваши обратные вызовы и проверки, вы можете использовать update_column v(3.1) или update_all

vote = Vote.first
vote.update_column(:subject, 'CallBacks')

По-видимому, это работает только с ActiveRecord 3.1

Или же:

Vote.where('id = ?', YourID).update_all(:subject => 'CallBacks')

В конце концов, у вас также есть опция "Наконец-то я", которая пропустит все:

execute "UPDATE votes SET subject = 'CallBacks' WHERE id = YourID"

ОК, последний не такой красивый.

Другие вопросы по тегам