Rails:获取除当前在 after_create 中创建的记录之外的所有记录

Rails: getting all records except currently created one in after_create

提问人:Corey 提问时间:9/14/2023 最后编辑:mechnicovCorey 更新时间:9/14/2023 访问量:27

问:

我在循环遍历所有记录时遇到了问题,除了 中新创建的记录。after_create

我的模型:

客户-has_many :registries

注册表-belongs_to :customer

基本上,我的注册表模型有一个名为“active”的字段,一次只能有 1 个注册表处于活动状态。“活动”字段的默认值为 。true

我在注册表模型上有一个after_create方法,该方法遍历客户拥有的所有注册表,但新创建的注册表除外,并将“active”设置为 。false

首先,很可能有更好的方法可以做到这一点。

但无论如何,我的内在看起来像这样:after_createregistry.rb

def deactivate_other_registries 
  customer.registries.where.not(id: id).each do |r|
    r.active = false
    r.save!
  end
end

这似乎断断续续地起作用,我认为这可能是由于比赛条件。

然后我试着把它改成:after_createafter_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

这似乎也没有解决我的问题。

我不确定如何实现我需要的东西?

Ruby-on-Rails 轨道-ActiveRecord

评论

1赞 mechnicov 9/14/2023
这回答了你的问题吗?Rails:确保一次只将一个布尔字段设置为 true

答:

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_commiton: :createon: :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