54

假设我在一个名为user_ids.

如果我想,比如说,把他们所有的名字都改成“Bob”,我可以这样做:

users = User.find(user_ids)
users.update_all( :name => 'Bob' )

不过,这不会触发回调。如果我需要在保存这些记录时触发回调,据我所知,唯一的方法是使用:

users = User.find(user_ids)
users.each do |u|
  u.name = 'Bob'
  u.save
end

然而,这可能意味着控制器操作中的一个非常长的运行任务。

所以,我的问题是,是否有任何其他更好/更高性能/更高效的方式来触发对一组记录的批量更新,从而触发记录的回调?

4

3 回答 3

69

不要使用 each/find_each,update而是尝试使用方法:

models.update(column: value)

这只是以下内容的包装:

models.each{|x| x.update(column: value)}
于 2017-07-12T11:28:10.093 回答
22

不,要运行回调,您必须实例化一个昂贵的操作对象。我认为解决您的问题的唯一方法是将您在回调中执行的操作重构为单独的方法,该方法可以使用 select_all 方法检索到的数据而无需对象实例化。

于 2011-08-03T19:09:15.893 回答
22

这是触发回调的另一种方式。而不是使用

models.update_all(params)

您可以使用

models.find_each { |m| m.update_attributes(params) }

但是,如果您要处理大量数据,我不会推荐这种方法。
希望能帮助到你!

于 2014-05-13T18:44:14.620 回答