Ruby-on-rails Rails 3 检查属性是否更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5051135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:28:26  来源:igfitidea点击:

Rails 3 check if attribute changed

ruby-on-railsruby-on-rails-3

提问by pcasa

Need to check if a block of attributes has changed before update in Rails 3.

在 Rails 3 中更新之前需要检查属性块是否已更改。

street1, street2, city, state, zipcode

街道 1、街道 2、城市、州、邮政编码

I know I could use something like

我知道我可以使用类似的东西

if @user.street1 != params[:user][:street1]
  then do something....
end

But that piece of code will be REALLY long. Is there a cleaner way?

但是那段代码真的很长。有更干净的方法吗?

回答by Peter Brown

Check out ActiveModel::Dirty(available on all models by default). The documentation is really good, but it lets you do things such as:

查看ActiveModel::Dirty(默认适用于所有型号)。该文档非常好,但它可以让您执行以下操作:

@user.street1_changed? # => true/false

回答by campeterson

This is how I solved the problem of checking for changes in multiple attributes.

这就是我如何解决检查多个属性变化的问题。

attrs = ["street1", "street2", "city", "state", "zipcode"]

if (@user.changed & attrs).any?
  then do something....
end

The changedmethod returns an array of the attributes changed for that object.

changed方法返回为该对象更改的属性的数组。

Both @user.changedand attrsare arrays so I can get the intersection (see ary & other arymethod). The result of the intersection is an array. By calling any?on the array, I get true if there is at least one intersection.

两个@user.changedattrs是数组因此可以得到的交叉点(参见ary & other ary方法)。交集的结果是一个数组。通过调用any?数组,如果至少有一个交集,我就会得到 true。

Also very useful, the changed_attributesmethod returns a hash of the attributes with their original values and the changesreturns a hash of the attributes with their original and new values (in an array).

同样非常有用的是,该changed_attributes方法返回属性及其原始值changes的散列,并返回属性及其原始值和新值的散列(在数组中)。

You can check APIDock for which versions supported these methods.

您可以检查 APIDock 以了解哪些版本支持这些方法。

http://apidock.com/rails/ActiveModel/Dirty

http://apidock.com/rails/ActiveModel/Dirty

回答by hamstar

ActiveModel::Dirtydidn't work for me because the @model.update_attributes()hid the changes. So this is how I detected changes it in an updatemethod in a controller:

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

If you're trying to detect a lot of attribute changes it could get messy though. Probably shouldn't do this in a controller, but meh.

如果您试图检测大量属性更改,它可能会变得混乱。可能不应该在控制器中执行此操作,但是嗯。

回答by Lucas Andrade

For rails 5.1+ callbacks

对于 Rails 5.1+ 回调

As of Ruby on Rails 5.1, the attribute_changed?and attribute_wasActiveRecord methods will be deprecated

从 Ruby on Rails 5.1 开始,不推荐使用theattribute_changed?attribute_wasActiveRecord 方法

Use saved_change_to_attribute?instead of attribute_changed?

使用saved_change_to_attribute?代替attribute_changed?

@user.saved_change_to_street1? # => true/false

More examples here

更多例子在这里

回答by shubham mishra

Above answers are better but yet for knowledge we have another approch as well, Lets 'catagory' column value changed for an object (@design),

上面的答案更好,但对于知识,我们还有另一种方法,让“类别”列值更改为对象(@design),

@design.changes.has_key?('catagory')

The .changes will return a hash with key as column's name and values as a array with two values [old_value, new_value] for each columns. For example catagory for above is changed from 'ABC' to 'XYZ' of @design,

.changes 将返回一个散列,键作为列的名称,值作为一个数组,每个列有两个值 [old_value, new_value]。例如上面的类别从@design的“ABC”更改为“XYZ”,

@design.changes   # => {} 
@design.catagory = 'XYZ'
@design.changes # => { 'catagory' => ['ABC', 'XYZ'] }

For references change in ROR

对于ROR 中的参考更改