2009-08-27 99 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