Rails状态机技术问询:如何让演员的粉丝同步切换至哭泣状态
解决Actor状态切换时同步Fan状态的问题
嘿,刚接触Rails状态机的话,这个需求其实很好实现~我一步步给你讲怎么改:
第一步:修正Fan模型的小问题 + 完善状态机
首先你代码里Fan的belongs_to :author应该是belongs_to :actor吧?毕竟是关联Actor的粉丝嘛😉。然后把Fan的状态机补全,和Actor保持一致的状态和事件:
class Fan < ApplicationRecord include AASM belongs_to :actor # 这里改成:actor,不是:author哦 aasm do state :laughing, initial: true state :crying event :cry do transitions from: :laughing, to: :crying end event :laugh do transitions from: :crying, to: :laughing end end end
第二步:在Actor的cry事件里添加同步逻辑
接下来要让Actor切换到crying状态时,自动把所有关联的Fan也改成crying。我们可以利用AASM事件的after回调来实现,有两种常用方式:
方式一:逐个触发Fan的cry事件(推荐,保留状态机回调)
这种方式会触发Fan模型状态机的所有回调(比如如果Fan的cry事件有before/after逻辑的话),更符合状态机的设计:
class Actor < ApplicationRecord include AASM has_many :fans aasm do state :laughing, initial: true state :crying event :cry do transitions from: :laughing, to: :crying after do # 遍历所有粉丝,只给还没在crying状态的触发cry事件 fans.find_each do |fan| fan.cry! unless fan.crying? end end end event :laugh do transitions from: :crying, to: :laughing end end end
方式二:批量更新(效率更高,但跳过回调)
如果Fan的cry事件没有额外的回调逻辑,只是单纯改状态,用批量更新会更高效,直接操作数据库:
# 在Actor的cry事件after回调里替换成这段 fans.where(aasm_state: :laughing).update_all(aasm_state: :crying)
⚠️ 注意:update_all不会触发ActiveRecord的回调和状态机的回调,如果Fan的状态切换有额外逻辑(比如发通知、记录日志),一定要用方式一!
可选:同步laugh状态(如果需要的话)
要是之后需要Actor切换回laughing时,粉丝也同步改回去,用同样的方法在laugh事件里加after回调就行~
内容的提问来源于stack exchange,提问作者user5872304
相关产品推荐
相关产品推荐

