Merge pull request #18225 from DanOlson/update-without-changing-timestamps

Provide :touch option to save() to accommodate saving without updating t...
This commit is contained in:
Sean Griffin 2014-12-27 21:44:30 -07:00
commit 3ba552fb29
5 changed files with 48 additions and 10 deletions

@ -1,3 +1,10 @@
* Provide :touch option to save() to accommodate saving without updating
timestamps.
Fixes #18202
*Dan Olson*
* Provide a more helpful error message when an unsupported class is passed to
`serialize`

@ -298,7 +298,7 @@ def touch(*) #:nodoc:
private
def create_or_update #:nodoc:
def create_or_update(*) #:nodoc:
_run_save_callbacks { super }
end

@ -116,8 +116,8 @@ def persisted?
#
# Attributes marked as readonly are silently ignored if the record is
# being updated.
def save(*)
create_or_update
def save(*args)
create_or_update(*args)
rescue ActiveRecord::RecordInvalid
false
end
@ -138,8 +138,8 @@ def save(*)
#
# Attributes marked as readonly are silently ignored if the record is
# being updated.
def save!(*)
create_or_update || raise(RecordNotSaved.new(nil, self))
def save!(*args)
create_or_update(*args) || raise(RecordNotSaved.new(nil, self))
end
# Deletes the record in the database and freezes this instance to
@ -498,9 +498,9 @@ def relation_for_destroy
relation
end
def create_or_update
def create_or_update(*args)
raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
result = new_record? ? _create_record : _update_record
result = new_record? ? _create_record : _update_record(*args)
result != false
end

@ -57,8 +57,8 @@ def _create_record
super
end
def _update_record(*args)
if should_record_timestamps?
def _update_record(*args, touch: true, **options)
if touch && should_record_timestamps?
current_time = current_time_from_proper_timezone
timestamp_attributes_for_update_in_model.each do |column|
@ -67,7 +67,7 @@ def _update_record(*args)
write_attribute(column, current_time)
end
end
super
super *args
end
def should_record_timestamps?

@ -878,4 +878,35 @@ def test_find_via_reload
assert_equal "Welcome to the weblog", post.title
assert_not post.new_record?
end
class SaveTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
def test_save_touch_false
widget = Class.new(ActiveRecord::Base) do
connection.create_table :widgets, force: true do |t|
t.string :name
t.timestamps null: false
end
self.table_name = :widgets
end
instance = widget.create!({
name: 'Bob',
created_at: 1.day.ago,
updated_at: 1.day.ago
})
created_at = instance.created_at
updated_at = instance.updated_at
instance.name = 'Barb'
instance.save!(touch: false)
assert_equal instance.created_at, created_at
assert_equal instance.updated_at, updated_at
ensure
ActiveRecord::Base.connection.drop_table :widgets
end
end
end