我不确定用这句话的最好方法,所以让我来说明一下:
class Foo < ActiveRecord::Base
belongs_to :organization
enum state: [:active, :inactive]
end
如果我将任何foo更新为:active
,我需要将同一组织中的所有其他Foo更改为:inactive
。
但是,我不想过于急切,如果将Foo更改为active,则无法通过某种验证或以其他方式回滚。另一方面,我不能同时拥有两个Foos :active
。
我计划在after_commit挂钩中发送通知。但是如果我在after_update挂钩内更新:active
模型为:inactive
,那么我不知道是否仍会在主要事务内部对那些模型触发after_commit挂钩
答案 0 :(得分:1)
由于存在违反您的唯一约束并仅在经过一些检查后应用它的情况,我不建议查看数据库约束/条件唯一索引,除非您绝对想要解决竞争条件。< / p>
我认为如果你在你的模型中加入类似下面的东西,它应该可以工作:
class Foo < ActiveRecord::Base
# the following should be your last callback
after_update :unique_state
# replacing the enum with an easy-to-understand scope
scope :active, -> { where(state: true) }
private
def unique_state
# do nothing if state is false:
return unless state
Foo
.active
.where(organization_id: organization_id)
.where.not(id: id)
.update_all(state: false)
end
end
答案 1 :(得分:1)
我将上述评论复制为您问题的答案:
我认为不是在state
表中使用foos
列,active_foo_id
中的organizations
列会更好:)您只需要在需要时更新一条记录改变国家。
答案 2 :(得分:0)
我通过将列更改为名为active_as_of
的日期时间来解决此问题。通过简单的touch(:active_as_of)
实现特定记录的活动,并消除了多个活动记录的可能性。
这也解决了删除或停用活动记录的情况。在这种情况下,最近最活跃的记录将不间断地恢复其活动状态。