我有一个模型,如果它被赋予某种状态,则状态永远不会再被改变。我试图通过在模型上放入before_save来检查状态是什么来实现这一点,并在设置为某个状态时引发异常。
问题是这个 -
def raise_if_exported
if self.exported?
raise Exception, "Can't change an exported invoice's status"
end
end
工作正常,但是当我最初通过执行以下操作将状态设置为导出时 -
invoice.status = "Exported"
invoice.save
引发异常是因为状态已经设置为在模型上导出而不是db(我认为)
那么有没有办法阻止该属性在被设置为“已导出”后被更改?
答案 0 :(得分:3)
您可以根据需要使用验证器
class Invoice < ActiveRecord::Base
validates_each :status do |record, attr, value|
if ( attr == :status and status_changed? and status_was == "Exported")
record.errors.add(:status, "you can't touch this")
end
end
end
现在
invoice.status= "Exported"
invoice.save # success
invoice.status= "New"
invoice.save # error
答案 1 :(得分:1)
您还可以使用ActiveModel::Dirty
跟踪更改,而不是检查当前状态:
def raise_if_exported
if status_changed? && status_was == "Exported"
raise "Can't change an exported invoice's status"
end
end
试试这个,只有 if 你真的希望在保存时引发异常。如果没有,请在验证过程中检查它,如@Trip建议
有关详细信息,请参阅this page。
答案 2 :(得分:1)
我会选择@Trip和@Sikachu的答案:
validate :check_if_exported
def check_if_exported
if status_changed? && status_was.eql?("Exported")
errors.add(:status, " cannot be changed once exported.")
end
end
使模型失效是一种比仅仅抛出错误更好的响应,除非你 reeeally 想要这样做。
答案 3 :(得分:0)
在模型中尝试内置验证的Rails:
validate :check_if_exported
def check_if_exported
if self.exported?
errors.add(:exported_failure, "This has been exported already.")
end
end