Answers:
签出ActiveModel :: Dirty(默认情况下在所有模型上都可用)。该文档确实很好,但是它可以让您执行以下操作:
@user.street1_changed? # => true/false
这就是我解决检查多个属性更改的问题的方式。
attrs = ["street1", "street2", "city", "state", "zipcode"]
if (@user.changed & attrs).any?
then do something....
end
该changed
方法返回为该对象更改的属性的数组。
两个@user.changed
和attrs
是数组因此可以得到的交叉点(参见ary & other ary
方法)。相交的结果是一个数组。通过调用any?
数组,我知道是否存在至少一个交集。
该changed_attributes
方法也非常有用,它返回属性的哈希值及其原始值,并changes
返回属性的哈希值及其原始值和新值(在数组中)。
您可以检查APIDock哪些版本支持这些方法。
if attrs.any?{|attr| @user.send("#{attr}_changed?")}
当我想检查几个不同属性中的一个是否已更改时-当然,我只使用自己定义的attrs进行此操作,因为我不喜欢将用户参数放入send
方法中。;)
ActiveModel::Dirty
对我不起作用,因为@model.update_attributes()
隐藏了更改。因此,这就是我update
在控制器的方法中检测到更改的方式:
def update
@model = Model.find(params[:id])
detect_changes
if @model.update_attributes(params[:model])
do_stuff if attr_changed?
end
end
private
def detect_changes
@changed = []
@changed << :attr if @model.attr != params[:model][:attr]
end
def attr_changed?
@changed.include :attr
end
如果您尝试检测许多属性更改,则可能会变得混乱。可能不应该在控制器中执行此操作,但是。
previous_changes
默认情况下也可用。
#update_attributes
不会隐藏更改。它保存了记录,因此模型已更新且没有更改。您需要更改模型中的字段并changed?
在保存之前进行检查。即。@ model.field ='foo'或@model.attributes = @model.attributes.merge(params[:model])
上面的答案更好,但就我们所知,我们还有另一种方法,让对象的“ catagory”列值更改(@design),
@design.changes.has_key?('catagory')
.changes将返回一个哈希,其键为列名,值作为一个数组,每列具有两个值[old_value,new_value]。例如,上述类别从@design的“ ABC”更改为“ XYZ”,
@design.changes # => {}
@design.catagory = 'XYZ'
@design.changes # => { 'catagory' => ['ABC', 'XYZ'] }
供参考,以更改ROR