From 84d509af33fcf6ea620d2bae15beb43a7b51816a Mon Sep 17 00:00:00 2001 From: fatkodima Date: Sat, 31 Mar 2018 02:55:56 +0300 Subject: [PATCH] Ensure enum changes are stored consistently --- CHANGELOG.md | 3 ++- lib/audited/auditor.rb | 20 ++++++++++++++++---- spec/audited/auditor_spec.rb | 17 ++++++++++++++++- spec/support/active_record/models.rb | 1 + spec/support/active_record/schema.rb | 1 + 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7f75be45..52d923d5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,8 @@ Changed Fixed -- None +- Ensure enum changes are stored consistently + [#429](https://github.com/collectiveidea/audited/pull/429) ## 4.7.0 (2018-03-14) diff --git a/lib/audited/auditor.rb b/lib/audited/auditor.rb index 9ff0b3b93..ae95199ff 100644 --- a/lib/audited/auditor.rb +++ b/lib/audited/auditor.rb @@ -196,10 +196,22 @@ def revision_with(attributes) def audited_changes all_changes = respond_to?(:changes_to_save) ? changes_to_save : changes - if audited_options[:only].present? - all_changes.slice(*self.class.audited_columns) - else - all_changes.except(*self.class.non_audited_columns) + filtered_changes = \ + if audited_options[:only].present? + all_changes.slice(*self.class.audited_columns) + else + all_changes.except(*self.class.non_audited_columns) + end + + filtered_changes = normalize_enum_changes(filtered_changes) + filtered_changes.to_hash + end + + def normalize_enum_changes(changes) + changes.each do |key, value| + if enum = self.class.defined_enums[key] + changes[key] = value.map { |v| enum[v] } + end end end diff --git a/spec/audited/auditor_spec.rb b/spec/audited/auditor_spec.rb index 174dbe683..8bee2648b 100644 --- a/spec/audited/auditor_spec.rb +++ b/spec/audited/auditor_spec.rb @@ -288,7 +288,7 @@ def non_column_attr=(val) describe "on update" do before do - @user = create_user( name: 'Brandon', audit_comment: 'Update' ) + @user = create_user( name: 'Brandon', status: 0, audit_comment: 'Update' ) end it "should save an audit" do @@ -312,6 +312,11 @@ def non_column_attr=(val) expect(@user.audits.last.audited_changes).to eq({ 'name' => ['Brandon', 'Changed'] }) end + it "should store changed enum as integers" do + @user.update_attributes status: 1 + expect(@user.audits.last.audited_changes["status"]).to eq([0, 1]) + end + it "should store audit comment" do expect(@user.audits.last.comment).to eq('Update') end @@ -628,6 +633,16 @@ def stub_global_max_audits(max_audits) expect(u.revision(1).username).to eq('brandon') end + it "should correctly restore revision with enum" do + u = Models::ActiveRecord::User.create(status: :active) + u.update_attribute(:status, :reliable) + u.update_attribute(:status, :banned) + + expect(u.revision(3)).to be_banned + expect(u.revision(2)).to be_reliable + expect(u.revision(1)).to be_active + end + it "should be able to get time for first revision" do suspended_at = Time.zone.now u = Models::ActiveRecord::User.create(suspended_at: suspended_at) diff --git a/spec/support/active_record/models.rb b/spec/support/active_record/models.rb index 701445f48..12c851496 100644 --- a/spec/support/active_record/models.rb +++ b/spec/support/active_record/models.rb @@ -7,6 +7,7 @@ class User < ::ActiveRecord::Base audited except: :password attribute :non_column_attr if Rails.version >= '5.1' attr_protected :logins if respond_to?(:attr_protected) + enum status: { active: 0, reliable: 1, banned: 2 } def name=(val) write_attribute(:name, CGI.escapeHTML(val)) diff --git a/spec/support/active_record/schema.rb b/spec/support/active_record/schema.rb index f340ff0c4..31319e022 100644 --- a/spec/support/active_record/schema.rb +++ b/spec/support/active_record/schema.rb @@ -35,6 +35,7 @@ t.column :username, :string t.column :password, :string t.column :activated, :boolean + t.column :status, :integer, default: 0 t.column :suspended_at, :datetime t.column :logins, :integer, default: 0 t.column :created_at, :datetime