2009-08-27 96 views
65

可能重複:
How can I avoid running ActiveRecord callbacks?如何跳過ActiveRecord回調?

我有這樣

class Vote < ActiveRecord::Base 
    after_save :add_points_to_user 

    ..... 
end 

模型是否有可能以某種方式強制模型保存時跳過調用add_points_to_user?可能類似ActiveRecord#delete vs ActiveRecord#destroy

+0

依我拙見,就是聲稱已經有一個答案的問題,只是打破答案。所以我認爲這不符合重複。我認爲我在下面提供的答案是正式批准的回調抵消方法。 – sheldonh 2013-06-26 11:12:31

回答

29

對於梁2,但不是Rails 3中,你可以使用這些:

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

可惜這不再是工作的Rails 3 :( – 2011-06-29 19:07:23

+2

見我的意見的回答,涵蓋軌道2和Rails 3 – sheldonh 2011-12-07 19:05:50

+3

那'Model'是誤導性的,那些是AR的情況下,不classmethods的方法,所以'record.send(: create_without_callbacks)'。 – tokland 2012-08-01 07:27:27

151

對於Rails 3中,ActiveSupport::Callbacks爲您提供了必要的控制。在數據集成場景中,我正面臨着同樣的挑戰,那就是需要將通常需要的回調放在一邊。您可以reset_callbacks EN-集體,或使用skip_callback明智禁用,像這樣:

,你可以在投票情況與操作
Vote.skip_callback(:save, :after, :add_points_to_user) 

..after:add_points_to_user抑制

+37

如果你不想擺脫回調的永久,但只說了一個創建/然後保存你將有你做跳繩回調後,使回: 'User.set_callback:保存:後:add_points_to_user' 也不要注意到,如果什麼都你2個調用之間做可能會引發異常你也許應該把它包圍繞開始( - 救援) - 保證 - 阻止。 – Timo 2011-07-01 08:07:53

+6

是否有特定的ins ,孟清湘? – EyalB 2012-09-04 12:19:38

+6

什麼我可能會建議是,聲明在類的''設置skip_callback':像'如果if'選項:拉姆達{@skip_callbacks ==真}',並在您需要爲此編寫方法來包裝情況:'def some_special_operation !; @skip_callbacks = true;做一點事;保存!; @skip_callbacks = false; end'可以使用一個上下文管理器方法來設置/取消ivar和yield到一個塊,但是如果你需要這個很多,可能會出現錯誤;-) **編輯**呃,我討厭SO評論換行限制。 – ches 2012-10-15 09:08:19

41

以下適用於軌道2,軌道3個與軌道4:

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

它提供的是跳過回調,解釋爲什麼它是危險使用它們沒有認真考慮方法的列表。根據知識共享署名 - 相同方式共享3.0許可條款轉載。

12跳繩回調

正如驗證,還可以跳過回調。但是,這些 方法應謹慎使用,因爲重要的業務規則和應用程序邏輯可能保留在回調中。 繞過它們而不理解潛在影響可能會導致無效數據 。

  • 遞減
  • decrement_counter
  • 刪除
  • DELETE_ALL
  • 的find_by_sql
  • 增量
  • increment_counter
  • 撥動
  • 觸摸
  • update_column
  • update_all
  • update_counters
+0

很高興知道!並且效果很好 – Ben 2014-07-09 16:40:49

+0

據我所知,在Rails 4.2中,只切換改變對象,但沒有保存到數據庫,你需要在切換後調用save方法。如果使用切換!,它現在保存,但它會觸發回調,所以,它應該從這個列表中刪除。 – zw963 2015-06-09 11:04:18

+0

@ zw963但切換!不在列表中,所以不需要刪除。你是否說非砰砰聲切換也會觸發回調,因此需要刪除?關於ActiveRecord回調的Rails指南仍然列出了跳過4.2.1中回調的方法之間的切換。 – sheldonh 2015-06-10 12:17:42

28

這將跳過你的驗證:

vote.save(:validate => false) 

更多信息here

要跳過你的回調和驗證,就可以使用, update_column v(3.1)或update_all

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

Aparentlly這隻能通過ActiveRecord 3.1

或者:

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

最後,你有我也終於選項,這將跳過寄託都:

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

OK最後一個不是很漂亮。

+3

這不會跳過回調,只是驗證 – pduersteler 2012-02-21 10:07:20

+0

update_all不跳過來自http://apidock.com/rails/ActiveRecord/Relation/update_all的回調:「它不會實例化相關模型,並且不會觸發Active Record回調或驗證「。 – 2012-07-25 18:06:01

+2

update_column也適用,除了上面的語法不正確。它期望2個參數:vote.update_column(:subject,'CallBacks') – 2012-08-14 00:00:26