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)。但是,只要查看源代碼就可以很容易地重新實現該方法。 –