web-dev-qa-db-ja.com

ActiveRecordコールバックをスキップする方法は?

可能性のある複製:
ActiveRecordコールバックの実行を回避するにはどうすればよいですか?

このようなモデルがあります

class Vote < ActiveRecord::Base  
    after_save :add_points_to_user

    .....
end

保存時にモデルを強制的にadd_points_to_userの呼び出しをスキップさせることは可能ですか?おそらくActiveRecord#delete vs ActiveRecord#destroyのようなものですか?

73
Jakub Arnold

Rails 2ではなく、Rails 3ではなく、これらを使用できます。

object.send(:create_without_callbacks)
object.send(:update_without_callbacks)
29
Stan Bright

Rails 3、 ActiveSupport :: Callbacks は必要な制御を提供します。通常は望ましいコールバックが必要なデータ統合シナリオで同じ課題に直面していました次のように、re-set_callbacks en-masseを使用するか、skip_callbackを使用して慎重に無効にすることができます。

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

..その後、add_points_to_userを禁止してVoteインスタンスを操作できます

164
tardate

以下は、Rails 2、Rails 3およびRails 4:

http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#skipping-callbacks

コールバックをスキップするメソッドのリストを提供し、慎重に検討せずにそれらを使用することが危険な理由を説明します。 Creative Commons Attribution-Share Alike 3.0 Licenseの条項に基づいてここに転載されています。

12コールバックのスキップ

検証と同様に、コールバックをスキップすることもできます。ただし、重要なビジネスルールとアプリケーションロジックがコールバックに保持される可能性があるため、これらのメソッドは注意して使用する必要があります。潜在的な影響を理解せずにそれらをバイパスすると、無効なデータにつながる可能性があります。

  • デクリメント
  • decrement_counter
  • 削除する
  • すべて削除
  • find_by_sql
  • インクリメント
  • increment_counter
  • toggle
  • タッチ
  • update_column
  • update_all
  • update_counters
45
sheldonh

これにより、検証がスキップされます。

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"

最後の1つはそれほどきれいではありません。

29
workdreamer