From 8b8d9a45e414b91cfca55a5da1860771e59fad4f Mon Sep 17 00:00:00 2001 From: Tyler Rick Date: Mon, 22 Jan 2018 11:14:17 -0800 Subject: [PATCH] - Add Changelog entry for `paper_trail.update_columns` - Use a guard in `record_update_columns` - Use Timecop.freeze so that we can guarantee that an expectation will pass - Add some comments --- CHANGELOG.md | 2 +- lib/paper_trail/record_trail.rb | 24 ++++++++++++++---------- spec/models/widget_spec.rb | 3 +-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ceeb2cb3..64531ec44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/). ### Added -- None +- [#1037](https://github.com/airblade/paper_trail/pull/1037) Add `paper_trail.update_columns` ### Fixed diff --git a/lib/paper_trail/record_trail.rb b/lib/paper_trail/record_trail.rb index 25ac7e902..e579627da 100644 --- a/lib/paper_trail/record_trail.rb +++ b/lib/paper_trail/record_trail.rb @@ -302,16 +302,16 @@ def data_for_update merge_metadata_into(data) end + # @api private def record_update_columns(changes) - if enabled? - versions_assoc = @record.send(@record.class.versions_association_name) - version = versions_assoc.create(data_for_update_columns(changes)) - if version.errors.any? - log_version_errors(version, :update) - else - update_transaction_id(version) - save_associations(version) - end + return unless enabled? + versions_assoc = @record.send(@record.class.versions_association_name) + version = versions_assoc.create(data_for_update_columns(changes)) + if version.errors.any? + log_version_errors(version, :update) + else + update_transaction_id(version) + save_associations(version) end end @@ -323,7 +323,6 @@ def data_for_update_columns(changes) object: recordable_object, whodunnit: PaperTrail.whodunnit } - data[:created_at] = Time.now if record_object_changes? data[:object_changes] = recordable_object_changes(changes) end @@ -437,13 +436,18 @@ def touch_with_version(name = nil) # Like the `update_column` method from `ActiveRecord::Persistence`, but also # creates a version to record those changes. + # @api public def update_column(name, value) update_columns(name => value) end # Like the `update_columns` method from `ActiveRecord::Persistence`, but also # creates a version to record those changes. + # @api public def update_columns(attributes) + # `@record.update_columns` skips dirty tracking, so we can't just use `@record.changes` or + # @record.saved_changes` from `ActiveModel::Dirty`. We need to build our own hash with the + # changes that will be made directly to the database. changes = {} attributes.each do |k, v| changes[k] = [@record[k], v] diff --git a/spec/models/widget_spec.rb b/spec/models/widget_spec.rb index c5b27ccde..7d0aef219 100644 --- a/spec/models/widget_spec.rb +++ b/spec/models/widget_spec.rb @@ -289,9 +289,8 @@ it "creates a version record" do widget = Widget.create expect(widget.versions.count).to eq(1) - Timecop.travel 1.second.since # because MySQL lacks fractional seconds precision + Timecop.freeze Time.now widget.paper_trail.update_columns(name: "Bugle") - # widget.update_attributes(name: "Bugle") expect(widget.versions.count).to eq(2) expect(widget.versions.last.event).to(eq("update")) expect(widget.versions.last.changeset[:name]).to eq([nil, "Bugle"])