提问人:Corey 提问时间:9/14/2023 最后编辑:mechnicovCorey 更新时间:9/14/2023 访问量:27
Rails:获取除当前在 after_create 中创建的记录之外的所有记录
Rails: getting all records except currently created one in after_create
问:
我在循环遍历所有记录时遇到了问题,除了 中新创建的记录。after_create
我的模型:
客户-has_many :registries
注册表-belongs_to :customer
基本上,我的注册表模型有一个名为“active”的字段,一次只能有 1 个注册表处于活动状态。“活动”字段的默认值为 。true
我在注册表模型上有一个after_create方法,该方法遍历客户拥有的所有注册表,但新创建的注册表除外,并将“active”设置为 。false
首先,很可能有更好的方法可以做到这一点。
但无论如何,我的内在看起来像这样:after_create
registry.rb
def deactivate_other_registries
customer.registries.where.not(id: id).each do |r|
r.active = false
r.save!
end
end
这似乎断断续续地起作用,我认为这可能是由于比赛条件。
然后我试着把它改成:after_create
after_save
def deactivate_other_registries
if new_record?
customer.registries.where.not(id: id).each do |r|
r.active = false
r.save!
end
end
end
这似乎也没有解决我的问题。
我不确定如何实现我需要的东西?
答:
0赞
trh
9/14/2023
#1
除非您有理由需要记录其他注册表时的时间戳,否则我建议使用 update_all,而无需在保存时运行生命周期事件。它将减少您的比赛条件。
after_create :deactivate_other_registries
def deactivate_other_registries
self.customer.registries.where.not(id: self.id)&.update_all(active: false)
end
评论
0赞
mechnicov
9/14/2023
你不需要和这里self
&
0赞
Corey
9/14/2023
#2
我最终将回调更改为:
after_commit :deactivate_other_registries, on: :create
然后:
def deactivate_other_registries
customer.registries.where.not(id: self.id).update_all(active: false)
end
这似乎对我有用。
0赞
mechnicov
9/14/2023
#3
由于一次只能激活 1 个注册表,因此看起来您不仅需要 ,还需要(假设您将手动激活一些注册表)after_commit
on: :create
on: :update
为此,Rails 6 引入了 after_save_commit
假设您需要创建新的非活动注册表,在这种情况下,活动注册表将被停用,这不是好的行为
最后,我建议这样的代码:
after_save_commit, if: :active?
private
def deactivate_other_registries
customer.registries.where.not(id: id).update_all(active: false)
end
评论