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

zyfwsgd6  于 2023-10-21  发布在  Ruby
关注(0)|答案(3)|浏览(136)

我在循环所有记录时遇到了一个问题,除了在after_create中新创建的记录。
我的模特:
客户-has_many :registries
注册表-belongs_to :customer
基本上我的注册表模型有一个名为“活动”的字段,一次只能激活1个注册表。“active”字段的默认值是true
我在注册表模型上有一个after_create方法,它循环客户拥有的所有注册表,除了新创建的注册表,并将“active”设置为false
首先,很可能有更好的方法来做到这一点。
但无论如何,我的registry.rb中的after_create看起来像这样:

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

这似乎也没有解决我的问题。
我不知道如何实现我所需要的。

tvokkenx

tvokkenx1#

除非你有理由需要一个时间戳的记录,当其他注册表我建议使用update_all,而不运行通过生命周期事件的保存。它会减少你的比赛条件。

after_create :deactivate_other_registries

def deactivate_other_registries
  self.customer.registries.where.not(id: self.id)&.update_all(active: false)
end
fafcakar

fafcakar2#

最后,我把回调改为:

after_commit :deactivate_other_registries, on: :create

然后:

def deactivate_other_registries
 customer.registries.where.not(id: self.id).update_all(active: false)
end

这似乎对我起了作用。

li9yvcax

li9yvcax3#

由于一次只能激活一个注册表,看起来您不仅需要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

相关问题