1

我有一个模型,如果它被赋予某种状态,则该状态将永远无法再次更改。我试图通过在模型上放置一个 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

引发异常是因为状态已经设置为模型而不是数据库上的导出(我认为)

那么,一旦将其设置为“导出”,有没有办法防止该属性被更改?

4

4 回答 4

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
于 2012-07-12T00:38:22.630 回答
1

您还可以使用ActiveModel::Dirty来跟踪更改,而不是检查当前状态:

def raise_if_exported
  if status_changed? && status_was == "Exported"
    raise "Can't change an exported invoice's status"
  end
end

您真的希望在保存时引发该异常时,请尝试此操作。如果没有,请在验证期间检查它,如@Trip 建议的那样

有关更多详细信息,请参阅此页面

于 2012-07-12T00:34:31.640 回答
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

使模型无效是比仅仅抛出错误更好的响应,除非你真的要这样做。

于 2012-07-12T00:59:19.257 回答
0

在你的模型中尝试 Rails 内置验证:

validate :check_if_exported

def check_if_exported
  if self.exported?
    errors.add(:exported_failure, "This has been exported already.")
  end
end
于 2012-07-12T00:32:09.810 回答