我正在构建一个 Rails 3.2 应用程序,我必须将 Sidekiq 作业封装在一个单独的模型中,以维护关系并处理插入和删除。
我使用 Mongoid 作为我的主要 ORM,我想问我如何制作不可变的记录。
这意味着在(初始化和)创建作业之后,除了删除记录之外,不接受任何更改。
谢谢!
我正在构建一个 Rails 3.2 应用程序,我必须将 Sidekiq 作业封装在一个单独的模型中,以维护关系并处理插入和删除。
我使用 Mongoid 作为我的主要 ORM,我想问我如何制作不可变的记录。
这意味着在(初始化和)创建作业之后,除了删除记录之外,不接受任何更改。
谢谢!
假设您的 Rails 应用程序是唯一的 MongoDB 客户端,您可以在模型层实现不变性逻辑:
class Job
include Mongoid::Document
before_validation { false if changed? && persisted? }
end
第一次调用save
或调用create
newJob
时,数据将成功保存。调用时,对对象的进一步更改不会写入数据库save
。的行为delete
将不受影响。
为什么这有效
before_validation
如果返回 false,则取消持久性:
如果 before_validation 回调的返回值可以评估为 false,则该过程将中止并且 Base#save 将返回 false。如果 ActiveRecord::Validations#save! 调用它会引发 ActiveRecord::RecordInvalid 异常。不会将任何内容附加到错误对象。
方法参考
我扩展了塞巴斯蒂安的出色回答,以使行为更清晰。
class Job
include Mongoid::Document
field :msg, type: String
validate :immutability
def immutability
if changed? && persisted?
errors[:base] << "#{self.class.name} is immutable and cannot be modified after it has been persisted"
end
end
end
这是它的工作原理:
> job = Job.create(msg: 'Hello')
=> #<Job _id: 55a7ccb76d61634e87000000, msg: "Hello">
> job.update_attributes!(msg: 'Goodbye')
Mongoid::Errors::Validations:
Problem:
Validation of Job failed.
Summary:
The following errors were found: Job is immutable and cannot be modified after it has been persisted
Resolution:
Try persisting the document with valid data or remove the validations.
from /...
> job.destroy!
=> true
这有两个主要好处:
before_validation
( Calling update_attributes! on Job resulted in a false return from a callback.
)得到的解释性强得多