[英]Overload and Bypass Active Record Update
我正在尝试在我的应用程序中实施审核跟踪,但是由于某些要求,我无法使用任何现有的gem或插件。
我想将任何将模型更新的常规尝试转移到将所有更新保存在另一个单独的表(称为“更新”)中的自定义方法。
然后,应用程序使用更新表来实际执行更新。
现在,我已经重载了create_or_update以获得功能的第一部分
def create_or_update
raise ReadOnlyRecord if readonly?
result = new_record? ? create : create_updates
result != false
end
class Update < ActiveRecord::Base
belongs_to :updatable, :polymorphic => true
after_create :update_model
private
def update_model
self.updatable.update_attribute self.attribute, self.new_value #infinite loop
end
end
现在的问题是,当更新模型尝试实际执行更新时,这将导致无限循环。
我一直在寻找Rails核心资源,以找到绕过第一个功能的最佳位置。 我希望在事务内部执行这些更新,但是我不确定活动记录堆栈中的确切开始或结束位置。 我也不想开始破坏活跃的资源。
任何建议将不胜感激。
您实际上是否需要将属性保存在单独的表中,然后在管理员查看并批准它们之后执行更新? 如果是这种情况,您可能只想覆盖update方法来执行以下操作:
def update(perform_updates = false)
if perform_updates
latest_approved_update = UpdateAuditor.first(:conditions => { :updatable_id => self.id, :updatable_type => self.class.name, :approved => true })
self.attributes = latest_approved_update.attributes
self.save
else
UpdateAuditor.create(:updatable_id => self.id, :updatable_type => self.class.name, :attributes => self.attributes)
end
end
更新:作者评论说,他们希望能够将此模型应用于所有更新。 为了做到这一点,您可以向模型添加attr_accessor,比如“ perform_updates”之类的东西,默认情况下当然为零。
要对数据库执行更新时,首先必须将属性设置为true,然后运行更新。 否则,更新将只创建一个新的UpdateAuditor记录,该记录需要得到管理员的批准。
class Person < ActiveRecord::Base
has_many :audits, :class_name => "UpdateAudit", :as => :auditable
attr_accessor :perform_updates
private
def create_or_update
raise ReadOnlyRecord if readonly?
if new_record?
result = create
result != false
else
if perform_updates
latest_approved_update = audits.approved.last
if latest_approved_update
self.attributes = latest_approved_update.attributes
update
else
return false
end
else
audits.create(:updated_attributes => self.attributes)
end
end
end
end
作为记录,我认为覆盖默认的更新方法是一个危险的游戏,这种编程最好在它所属的before_update
回调中进行。 一旦在某个界面中批准了更新,然后观察者就可以执行更新,覆盖当前存在的内容,直到可以批准进行的另一个更改。 如果队列中当前有待批准对象的更新,则可以提醒用户更改正在等待批准等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.