因此出现了工作情况,我想在这里讨论,因为我们无法达成协议:
我们有两个模型,Order
和Passport
,它们与订单has_one护照和护照has_many订单相关。订单完成后,其相关护照必须被锁定,即转为只读(该信息已用于清关,因此之后无法更改)。我们希望在Passport
模型中强制执行该规则,并且我们已经考虑了以下选项:
valid? => false
。例如,如果其他记录上有validates_associated :passport
,则可能会出现问题。readonly?
方法。缺点:这会在尝试更新该记录时引发异常,但您可能希望调用save
方法不会引发该记录。before_save
回调。这有两种风格:引发异常(与readonly?
选项非常相似)或添加@error
并返回false
以停止回调链。缺点:从正确的验证外部添加验证错误可被视为不良做法。此外,您可能会发现自己正在呼叫valid?
并获取true
,然后致电save
并获取false
。这种情况使我们对验证和Rails之间的关系有很多想法。记录valid?
到底意味着什么?这是否意味着save
会起作用?
我想听取您的意见,了解这种情况。也许最好的方法不是三者之一!谢谢!
答案 0 :(得分:0)
使用readonly!
实例方法将此记录标记为只读怎么样?请参阅API
您可以在构造函数中执行此操作,例如:
class Passport < ActiveRecord::Base
def initialize(*args)
super(*args)
readonly! if orders.count>0 # or similar
end
end
答案 1 :(得分:0)
我认为还有一个额外的选择。您所描述的内容表明Passport
模型可以有一些不同的状态。我会考虑使用状态机来描述护照的相关订单状态。
例如:
考虑到这一点,所有相关的订单操作都会触发护照模型及其状态的事件。
如果可以将更新操作集成到某些事件,那么您可以以更优雅的方式处理只读部分(不兼容的状态转换)。
作为额外的检查,您可以始终将丑陋的验证器作为最后的手段,以防止在没有状态机的情况下更新模型。
您可以查看the aasm gem了解此内容