Skip to content

Commit

Permalink
Store old and new values in the changes for each audit.
Browse files Browse the repository at this point in the history
  • Loading branch information
bkeepers committed Jan 26, 2009
1 parent 04c3815 commit 4c598c2
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 22 deletions.
26 changes: 12 additions & 14 deletions lib/acts_as_audited.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def acts_as_audited(options = {})
class_inheritable_reader :auditing_enabled

except = [self.primary_key, inheritance_column, 'lock_version', 'created_at', 'updated_at']
except |= [options[:except]].flatten.collect(&:to_s) if options[:except]
except |= Array(options[:except]).collect(&:to_s) if options[:except]
write_inheritable_attribute :non_audited_columns, except

has_many :audits, :as => :auditable, :order => "#{Audit.quoted_table_name}.version desc"
Expand All @@ -92,15 +92,6 @@ def acts_as_audited(options = {})

module InstanceMethods

def changed_audited_attributes
attributes.slice(*changed_attributes.keys).except(*non_audited_columns)
end

# Returns the attributes that are audited
def audited_attributes
attributes.except(*non_audited_columns)
end

# Temporarily turns off auditing while saving.
def save_without_auditing
without_auditing { save }
Expand Down Expand Up @@ -137,9 +128,16 @@ def revision_at(date_or_time)
:order => "created_at DESC")
revision_with changes_from(audit.version) if audit
end

private


def audited_changes
changed_attributes.except(*non_audited_columns).inject({}) do |changes,(attr, old_value)|
changes[attr] = [old_value, self[attr]]
changes
end
end

def changes_from(version = 1, &block)
if version == :previous
version = if self.version
Expand Down Expand Up @@ -173,11 +171,11 @@ def revision_with(attributes)
end

def audit_create(user = nil)
write_audit(:action => 'create', :changes => audited_attributes, :user => user)
write_audit(:action => 'create', :changes => audited_changes, :user => user)
end

def audit_update(user = nil)
unless (changes = changed_audited_attributes).empty?
unless (changes = audited_changes).empty?
write_audit(:action => 'update', :changes => changes, :user => user)
end
end
Expand Down
12 changes: 8 additions & 4 deletions lib/acts_as_audited/audit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,16 @@ def ancestors
end

def self.reconstruct_attributes(audits)
changes = {}
attributes = {}
result = audits.collect do |audit|
changes.merge!((audit.changes || {}).merge!(:version => audit.version))
yield changes if block_given?
changes = (audit.changes || {}).inject({}) do |changes,(attr,values)|
changes[attr] = Array(values).last
changes
end
attributes.merge!(changes).merge!(:version => audit.version)
yield attributes if block_given?
end
block_given? ? result : changes
block_given? ? result : attributes
end

private
Expand Down
8 changes: 4 additions & 4 deletions spec/acts_as_audited_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@
end

it "should store all the audited attributes" do
audit = create_user.audits.first
audit.changes.should == audit.auditable.audited_attributes
audit = User.create(:name => 'Brandon').audits.first
audit.changes.should == {'name' => [nil, 'Brandon']}
end
end

describe "on update" do
before do
@user = create_user
@user = create_user(:name => 'Brandon')
end

it "should save an audit on update" do
Expand All @@ -64,7 +64,7 @@

it "should store the changed attributes" do
@user.update_attributes :name => 'Changed'
@user.audits.first.changes.should == {'name' => 'Changed'}
@user.audits.first.changes.should == {'name' => ['Brandon', 'Changed']}
end

it "should not save an audit if the value doesn't change after type casting" do
Expand Down
7 changes: 7 additions & 0 deletions spec/audit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,12 @@
user.destroy
user.audits(true).first.version.should == 3
end

describe "reconstruct_attributes" do
it "should work with with old way of storing just the new value" do
audits = Audit.reconstruct_attributes([Audit.new(:changes => {'attribute' => 'value'})])
audits['attribute'].should == 'value'
end
end

end

0 comments on commit 4c598c2

Please sign in to comment.