我正在实施pluginaweek 的 state_machine gem。我将代码缩小到这个范围,以便我可以更轻松地理解问题。假设我现在只有一个状态:
class Event < ActiveRecord::Base
state_machine :status, :initial => :active_offer do
end
def status
'Active Offer'
end
end
通过播种或浏览器创建新事件对象时出现的错误是{:status=>["is invalid"]}
.
计划是包含所有不同状态的条件并将自定义字符串返回到视图。整个项目的视图当前都使用该.status
语法,所以我正在尝试顺利安装它。我基于阅读 api 文档开始了这个解决方案:
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Overwriting+default+accessors
这是我的主要目标:
def status
if read_attribute(:status) == 'active_offer' && self.start_date > Time.now
'Active Offer'
elsif read_attribute(:status) == 'active_offer' && self.start_date < Time.now
'Expired'
else read_attribute(:status) == 'cancelled'
'Cancelled'
end
end
我该怎么做才能使 state_machine 块使用普通访问器以便它获取数据库值?
银弹解决方案:
我的主要问题是访问器覆盖status
。当 state_machine 代码运行时,它正在通过我的访问器覆盖读取当前状态,因此返回了一个自定义字符串,这是一个无效状态。我不得不让 state_machine 使用 :state。我最初没有这样做,因为我已经有一个省等的:state attr,所以我将它迁移到:address_state。