我有两个班级:
class Account
has_many :follow_ups
end
class FollowUp
belongs_to :account
end
对于每个帐户,我都需要在completed_at
上引入FollowUp
列。我还需要为每个帐户执行以下操作:将completed_at
设置为1900年1月1日,除了最近创建的后续操作之外的每个后续操作。
我尝试将以下内容放入一个迁移文件中,但它将所有FollowUp
s completed_at
保留为nil
。
class AddCompletedAtToFollowUps < ActiveRecord::Migration[5.1]
def change
add_column :follow_ups, :completed_at, :datetime
set_all_but_most_recent_follow_ups_as_long_completed_for_each_account
end
private
def set_all_but_most_recent_follow_ups_as_long_completed_for_each_account
Account.all.each do |account|
all_but_most_recent_follow_up_for(account).find_each do |follow_up|
follow_up.update(completed_at: Time.utc(1900))
end
end
end
def all_but_most_recent_follow_up_for(account)
account.follow_ups.order(created_at: :desc).offset(1)
end
end
我知道这是一个可怕的O(n ^ 2)设置,但令我惊讶的是它甚至无法正常工作。
有人可以帮助我实现最快的查询吗?
P.S。 all_but_most_recent_follow_up_for(account).update_all
更新了FollowUps
的所有,这也是错误的。
答案 0 :(得分:0)
以下似乎运作良好。 (但我怀疑有更高效的东西,也许是避免迭代的东西。)
%
答案 1 :(得分:0)
如果您不介意使用大量SQL,可以使用OFFSET
子句:
class AddCompletedAtToFollowUps < ActiveRecord::Migration[5.1]
def change
add_column :follow_ups, :completed_at, :datetime
Account.find_each do |a|
FollowUp.update_all("completed_at = '#{Time.utc(1900)}' where id in (select id from follow_ups where account_id = #{a.id} order by created_at desc offset 1)")
end
end
end