2008-03-28 20:04:27 -04:00
|
|
|
require 'cases/helper'
|
2008-03-29 18:19:26 -04:00
|
|
|
require 'models/topic' # For booleans
|
|
|
|
require 'models/pirate' # For timestamps
|
2008-03-30 21:10:04 -04:00
|
|
|
require 'models/parrot'
|
2008-03-29 18:19:26 -04:00
|
|
|
|
|
|
|
class Pirate # Just reopening it, not defining it
|
|
|
|
attr_accessor :detected_changes_in_after_update # Boolean for if changes are detected
|
|
|
|
attr_accessor :changes_detected_in_after_update # Actual changes
|
|
|
|
|
|
|
|
after_update :check_changes
|
|
|
|
|
|
|
|
private
|
|
|
|
# after_save/update in sweepers, observers, and the model itself
|
|
|
|
# can end up checking dirty status and acting on the results
|
|
|
|
def check_changes
|
|
|
|
if self.changed?
|
|
|
|
self.detected_changes_in_after_update = true
|
|
|
|
self.changes_detected_in_after_update = self.changes
|
2008-03-28 20:04:27 -04:00
|
|
|
end
|
2008-03-29 18:19:26 -04:00
|
|
|
end
|
2008-03-28 20:04:27 -04:00
|
|
|
end
|
|
|
|
|
2008-03-30 21:10:04 -04:00
|
|
|
class DirtyTest < ActiveRecord::TestCase
|
2008-03-28 20:04:27 -04:00
|
|
|
def test_attribute_changes
|
|
|
|
# New record - no changes.
|
2008-03-29 18:19:26 -04:00
|
|
|
pirate = Pirate.new
|
|
|
|
assert !pirate.catchphrase_changed?
|
|
|
|
assert_nil pirate.catchphrase_change
|
2008-03-28 20:04:27 -04:00
|
|
|
|
2008-03-29 18:19:26 -04:00
|
|
|
# Change catchphrase.
|
|
|
|
pirate.catchphrase = 'arrr'
|
|
|
|
assert pirate.catchphrase_changed?
|
|
|
|
assert_nil pirate.catchphrase_was
|
|
|
|
assert_equal [nil, 'arrr'], pirate.catchphrase_change
|
2008-03-28 20:04:27 -04:00
|
|
|
|
|
|
|
# Saved - no changes.
|
2008-03-29 18:19:26 -04:00
|
|
|
pirate.save!
|
|
|
|
assert !pirate.catchphrase_changed?
|
|
|
|
assert_nil pirate.catchphrase_change
|
2008-03-28 20:04:27 -04:00
|
|
|
|
|
|
|
# Same value - no changes.
|
2008-03-29 18:19:26 -04:00
|
|
|
pirate.catchphrase = 'arrr'
|
|
|
|
assert !pirate.catchphrase_changed?
|
|
|
|
assert_nil pirate.catchphrase_change
|
2008-03-28 20:04:27 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_object_should_be_changed_if_any_attribute_is_changed
|
2008-03-29 18:19:26 -04:00
|
|
|
pirate = Pirate.new
|
|
|
|
assert !pirate.changed?
|
|
|
|
assert_equal [], pirate.changed
|
|
|
|
assert_equal Hash.new, pirate.changes
|
|
|
|
|
|
|
|
pirate.catchphrase = 'arrr'
|
|
|
|
assert pirate.changed?
|
|
|
|
assert_nil pirate.catchphrase_was
|
|
|
|
assert_equal %w(catchphrase), pirate.changed
|
|
|
|
assert_equal({'catchphrase' => [nil, 'arrr']}, pirate.changes)
|
|
|
|
|
|
|
|
pirate.save
|
|
|
|
assert !pirate.changed?
|
|
|
|
assert_equal [], pirate.changed
|
|
|
|
assert_equal Hash.new, pirate.changes
|
|
|
|
end
|
2008-03-28 20:04:27 -04:00
|
|
|
|
2008-03-30 21:10:04 -04:00
|
|
|
def test_attribute_will_change!
|
|
|
|
pirate = Pirate.create!(:catchphrase => 'arr')
|
|
|
|
|
|
|
|
pirate.catchphrase << ' matey'
|
|
|
|
assert !pirate.catchphrase_changed?
|
|
|
|
|
|
|
|
assert pirate.catchphrase_will_change!
|
|
|
|
assert pirate.catchphrase_changed?
|
|
|
|
assert_equal ['arr matey', 'arr matey'], pirate.catchphrase_change
|
|
|
|
|
|
|
|
pirate.catchphrase << '!'
|
|
|
|
assert pirate.catchphrase_changed?
|
|
|
|
assert_equal ['arr matey', 'arr matey!'], pirate.catchphrase_change
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_association_assignment_changes_foreign_key
|
|
|
|
pirate = Pirate.create!
|
|
|
|
pirate.parrot = Parrot.create!
|
|
|
|
assert pirate.changed?
|
|
|
|
assert_equal %w(parrot_id), pirate.changed
|
|
|
|
end
|
|
|
|
|
2008-03-29 18:19:26 -04:00
|
|
|
def test_attribute_should_be_compared_with_type_cast
|
|
|
|
topic = Topic.new
|
|
|
|
assert topic.approved?
|
|
|
|
assert !topic.approved_changed?
|
|
|
|
|
|
|
|
# Coming from web form.
|
|
|
|
params = {:topic => {:approved => 1}}
|
|
|
|
# In the controller.
|
|
|
|
topic.attributes = params[:topic]
|
|
|
|
assert topic.approved?
|
|
|
|
assert !topic.approved_changed?
|
2008-03-28 20:04:27 -04:00
|
|
|
end
|
2008-03-30 21:10:04 -04:00
|
|
|
|
|
|
|
def test_partial_update
|
|
|
|
pirate = Pirate.new(:catchphrase => 'foo')
|
2008-03-30 21:49:57 -04:00
|
|
|
old_updated_on = 1.hour.ago.beginning_of_day
|
2008-03-30 21:10:04 -04:00
|
|
|
|
|
|
|
with_partial_updates Pirate, false do
|
|
|
|
assert_queries(2) { 2.times { pirate.save! } }
|
2008-03-30 21:49:57 -04:00
|
|
|
Pirate.update_all({ :updated_on => old_updated_on }, :id => pirate.id)
|
2008-03-30 21:10:04 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
with_partial_updates Pirate, true do
|
|
|
|
assert_queries(0) { 2.times { pirate.save! } }
|
2008-03-30 21:49:57 -04:00
|
|
|
assert_equal old_updated_on, pirate.reload.updated_on
|
|
|
|
|
|
|
|
assert_queries(1) { pirate.catchphrase = 'bar'; pirate.save! }
|
|
|
|
assert_not_equal old_updated_on, pirate.reload.updated_on
|
2008-03-30 21:10:04 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def with_partial_updates(klass, on = true)
|
|
|
|
old = klass.partial_updates?
|
|
|
|
klass.partial_updates = on
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
klass.partial_updates = old
|
|
|
|
end
|
2008-03-28 20:04:27 -04:00
|
|
|
end
|