Как "update_attributes", не выполняя "before_save"? - PullRequest
23 голосов
/ 30 августа 2011

У меня before_save в моей Message модели, определенной так:

   class Message < ActiveRecord::Base
     before_save lambda { foo(publisher); bar }
   end

Когда я делаю:

   my_message.update_attributes(:created_at => ...)

foo и bar выполнены.

Иногда я хотел бы обновить поля сообщения без выполнения foo и bar.

Как я могу обновить, например, поле created_at (в базе данных) без выполнения foo и bar?

Ответы [ 5 ]

34 голосов
/ 30 августа 2011

В rails 3.1 вы будете использовать update_column .

В противном случае:

В общем, самый элегантный способ обойти обратные вызовы следующий:

class Message < ActiveRecord::Base
  cattr_accessor :skip_callbacks
  before_save lambda { foo(publisher); bar }, :unless => :skip_callbacks # let's say you do not want this callback to be triggered when you perform batch operations
end

Затем вы можете сделать:

Message.skip_callbacks = true # for multiple records
my_message.update_attributes(:created_at => ...)
Message.skip_callbacks = false # reset

Или только для одной записи:

my_message.update_attributes(:created_at => ..., :skip_callbacks => true)

Если вам это нужно специально для атрибута Time, тогда touch сделает то, что упоминает @lucapette.

17 голосов
/ 30 августа 2011

update_all не будет вызывать обратные вызовы

my_message.update_all(:created_at => ...)
# OR
Message.update_all({:created_at => ...}, {:id => my_message.id})

http://apidock.com/rails/ActiveRecord/Base/update_all/class

6 голосов
/ 30 августа 2011

Используйте метод touch . Это элегантно и делает именно то, что вы хотите

1 голос
/ 30 августа 2011

Вы также можете сделать ваше действие before_save условным.

Поэтому добавьте некоторую переменную field / instance и установите ее, только если вы хотите пропустить ее, и проверьте это в своем методе.

* 1006 Е.Г. *

before_save :do_foo_and_bar_if_allowed

attr_accessor :skip_before_save

def do_foo_and_bar_if_allowed
  unless @skip_before_save.present?
    foo(publisher)
    bar
  end
end

а потом где-то напиши

my_message.skip_before_save = true
my_message.update_attributes(:created_at => ...)
0 голосов
/ 14 октября 2017

update_column или update_columns - самый близкий метод к update_attributes, и он избегает обратных вызовов без необходимости обхода чего-либо вручную.

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