0

我需要比较两个活动的记录,并获得已更改列比较两个记录,并获得已更改列的名称在轨活动记录

#<Evaluation id: 1, name: "Foo", status: "yes", comments: "can be better", created_at: "2017-05-09 12:00:00", updated_at: "2017-05-09 12:00:00">  
#<Evaluation id: 2, name: "Foo", status: "yes", comments: "keep up the good work", created_at: "2017-05-09 12:05:00", updated_at: "2017-05-09 12:05:00"> 

我需要比较这两个记录,并得到的名称更改的列的名称。在这种情况下:comments, :created_at, :updated_at

我一直在使用的方法,如eql?record1.attributes.except('id') == record2.attributes.except('id')

这些只返回true或false我需要得到的列名,以及尝试。 这可以通过比较每列来完成,但我正在寻找任何其他选项。

回答

1

您可以使用activerecord-diff宝石

链接:https://github.com/tim/activerecord-diff

require 'active_record/diff' 

class User < ActiveRecord::Base 
    include ActiveRecord::Diff 
end 

alice = User.create(:name => 'alice', :email_address => '[email protected]') 

bob = User.create(:name => 'bob', :email_address => '[email protected]') 

alice.diff?(bob) # => true 

alice.diff(bob) # => {:name => ['alice', 'bob'], :email_address => ['[email protected]', '[email protected]']} 

alice.diff({:name => 'eve'}) # => {:name => ['alice', 'eve']} 
+0

看起来像它的缺失为Rails'4.2','5.0'一个Gemfile中和'5.1' - 那里有大约3年没有任何承诺。 (虽然它应该很容易更新!) –

+0

通过命令将对象更改为散列:obj.attributes然后安装gem hashdiff(https://github.com/liufengyun/hashdiff)并将其比较 – puneet18

+0

我可以确认activerecord-diff作品很棒的Rails 5.0.1和红宝石2.3.1。只需在你的application.rb文件中使用require'active_record/diff' – Augusto

2

你可以用一个小方法来为你做这个:

def diff_active_record(record_a, record_b) 
    (record_a.attributes.to_a - record_b.attributes.to_a).map(&:first) 
end 

这种方法将两个active_record对象(在这种情况下:record_a,record_b)来比较并生成已更改的属性名称数组。

你可以使用这样的:

diff_active_record(Evaluation.find(1), Evaluation.find(2)) 

以上将导致[:id, :comments, :created_at, :updated_at]

+1

有趣的是,在Rails版本中曾经有一个['Hash#diff'](https://apidock.com/rails/Hash/diff)方法'3.0.0' - '4.0.2',但是[无需替换](https://github.com/rails/rails/blob/c0c87922baf47eed64a53d3afceba978bb175da9/activesupport/lib/active_support/core_ext/hash/diff)。 RB#L9)。但是,只要查看源代码就可以很容易地重新实现该方法。 –