如何保存模型,而在Rails的运行回调

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何保存模型,而在Rails的运行回调相关的知识,希望对你有一定的参考价值。

我需要保存在Rails的模型时,计算值。所以,我呼吁calculate_averages作为一个Survey类的回调:

before_save :calculate_averages

但是,偶尔(和最初我有10K的记录需要此操作),我需要手动更新每个记录所有的平均值。没问题,我有一个像下面的代码:

Survey.all.each do |survey|
  survey.some_average = (survey.some_value + survey.some_other_value) / 2.to_f
  #and some more averages...
  survey.save!
end

即使在运行该代码之前,我担心的calculate_averages将会被调用并复制这甚至可能导致一些问题的,我做事情的方式。好了,那么我想,好吧我就什么也不做,让calculate_averages得到打来电话,做它的事。问题有,第一,有没有办法迫使回调,如果你做出任何更改的记录进行报复叫什么?

其次,平均的方式计算它更有效地根本就没有让回调被调用的一切,做的一切平均值的一次。这可能不会让回调被调用?

答案

我相信你问什么可以ActiveSupport::Callbacks实现。看看set_callbackskip_callback

为了“逼回调,如果你做任何更改记录得到甚至被称为”,你需要回调例如注册一些事件save, validate etc.

set_callback :save, :before, :my_before_save_callback

要跳过before_save回调,你会怎么做:

Survey.skip_callback(:save, :before, :calculate_average). 

请参考其他支持选项,如条件和块ActiveSupport::Callbacksset_callback链接skip_callback

另一答案

要禁用EN-质量回调使用...

Survey.skip_callback(:save, :before, :calculate_averages)

然后让他们...

Survey.set_callback(:save, :before, :calculate_average)

此跳过/套所有实例。

另一答案

update_column是不运行任何回调的ActiveRecord功能,而且它也不会运行验证。

另一答案

如果你想检查每个之后有条件地跳过回调调查您可以编写自定义的方法。

对于前。

  • 修改callback-

`

before_save :calculate_averages, if: Proc.new{ |survey| !survey.skip_callback }

`

  • 新的实例方法 -

`

def skip_callback(value = false)
  @skip_callback = @skip_callback ? @skip_callback : value
end

`

  • 脚本来更新检验─

`

Survey.all.each do |survey|
  survey.some_average = (survey.some_value + survey.some_other_value) / 2.to_f
  #and some more averages...
  survey.skip_callback(true)
  survey.save!
end

`

它有点本事,但希望会为你工作。

另一答案

为Rails不起作用5

Survey.skip_callback(:save, :before, :calculate_average) 

作品为Rails 5

Survey.skip_callback(:save, :before, :calculate_average, raise: false)

https://github.com/thoughtbot/factory_bot/issues/931

另一答案

希望这是你在找什么。

https://stackoverflow.com/a/6587546/2238259

对于你的第二个问题,我怀疑这将是更好的检查时,这种计算需要发生,那将是最好的,如果它可以在批量在指定的时间,其中的网络流量是在谷底处理。

编辑:Woops。我居然发现2个链接,但失去了第一个,显然。希望你把它修好。

另一答案

为Rails 3 ActiveSupport::Callbacks为您提供了必要的控制。您可以reset_callbacks EN-集体,或使用skip_callback明智地禁止这样的:

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

......之后,你可以投票情况与:add_points_to_user操作抑制

另一答案

Rails的5.2.3要求当事人脚本后,以不触发模型事件,update_column(列,值)的伎俩:

task.update_column(task_status, ReferenceDatum::KEY_COMPLETED)

https://apidock.com/rails/ActiveRecord/Persistence/update_column

以上是关于如何保存模型,而在Rails的运行回调的主要内容,如果未能解决你的问题,请参考以下文章

Rails - 使用特定属性值缓存所有用户

rails回调未得到执行

确定 Rails after_save 回调中更改了哪些属性?

Rails - 如何从after_save回调中查看旧模型值和新模型值?

插入后的 Rails 回调

Rails 模型中的条件回调?