Как я могу избежать запуска обратных вызовов ActiveRecord? - PullRequest
130 голосов
/ 11 марта 2009

У меня есть некоторые модели с обратными вызовами after_save. Обычно это нормально, но в некоторых ситуациях, например, при создании данных разработки, я хочу сохранить модели без запуска обратных вызовов. Есть ли простой способ сделать это? Что-то похожее на ...

Person#save( :run_callbacks => false )

или

Person#save_without_callbacks

Я посмотрел в документации по Rails и ничего не нашел. Однако, по моему опыту, документы Rails не всегда рассказывают всю историю.

UPDATE

Я нашел пост в блоге , в котором объясняется, как можно удалить обратные вызовы из модели, подобной этой:

Foo.after_save.clear

Я не смог найти, где описан этот метод, но, похоже, он работает.

Ответы [ 25 ]

0 голосов
/ 11 марта 2009

Не самый чистый способ, но вы можете заключить код обратного вызова в условие, которое проверяет среду Rails.

if Rails.env == 'production'
  ...
0 голосов
/ 07 марта 2016

То, что должно работать со всеми версиями ActiveRecord без зависимости от параметров или методов activerecord, которые могут существовать или не существовать.

module PlainModel
  def self.included(base)
    plainclass = Class.new(ActiveRecord::Base) do
      self.table_name = base.table_name
    end
    base.const_set(:Plain, plainclass)
  end
end


# usage
class User < ActiveRecord::Base
  include PlainModel

  validates_presence_of :email
end

User.create(email: "")        # fail due to validation
User::Plain.create(email: "") # success. no validation, no callbacks

user = User::Plain.find(1)
user.email = ""
user.save

TLDR: использовать «другую модель активной записи» поверх той же таблицы

0 голосов
/ 11 марта 2009

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

Если вы хотите заполнить свою базу данных dev данными, лучшим подходом будет создание задачи rake, которая использует гем faker для построения правильных данных и импорта их в базу данных, создавая столько или несколько записей, сколько вы хотите, но если вы склонны к этому и у вас есть веская причина, я думаю, что update_without_callbacks и create_without_callbacks будут работать нормально, но когда вы пытаетесь склонить рельсы к своей воле, спросите себя, есть ли у вас веская причина, и действительно ли то, что вы делаете, действительно хорошо идея.

0 голосов
/ 15 августа 2009

Другим способом будет использование проверочных хуков вместо обратных вызовов. Например:

class Person < ActiveRecord::Base
  validate_on_create :do_something
  def do_something
    "something clever goes here"
  end
end

Таким образом вы можете получить do_something по умолчанию, но вы можете легко переопределить его с помощью:

@person = Person.new
@person.save(false)
0 голосов
/ 06 июня 2011

Один вариант - иметь отдельную модель для таких манипуляций, используя ту же таблицу:

class NoCallbacksModel < ActiveRecord::Base
  set_table_name 'table_name_of_model_that_has_callbacks'

  include CommonModelMethods # if there are
  :
  :

end

(тот же подход может облегчить обход проверок)

Stephan

...