Created
December 5, 2013 15:25
-
-
Save senny/7807422 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[33m0463698[m[32m (HEAD, 4-0-stable)[m Merge pull request #12646 from severin/polymorphic_belongs_to_touch [31m[Yves Senn][m [36m[27 seconds ago][m | |
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md | |
index 852be57..adc7003 100644 | |
--- a/activerecord/CHANGELOG.md | |
+++ b/activerecord/CHANGELOG.md | |
@@ -1,3 +1,17 @@ | |
+* Polymorphic belongs_to associations with the `touch: true` option set update the timestamps of | |
+ the old and new owner correctly when moved between owners of different types. | |
+ | |
+ Example: | |
+ | |
+ class Rating < ActiveRecord::Base | |
+ belongs_to :rateable, polymorphic: true, touch: true | |
+ end | |
+ | |
+ rating = Rating.create rateable: Song.find(1) | |
+ rating.update_attributes rateable: Book.find(2) # => timestamps of Song(1) and Book(2) are updated | |
+ | |
+ *Severin Schoepke* | |
+ | |
* Fix `last` with `offset` to return the proper record instead of always the last one. | |
Example: | |
diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb | |
index e8ae05d..7179726 100644 | |
--- a/activerecord/lib/active_record/associations/builder/belongs_to.rb | |
+++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb | |
@@ -73,7 +73,13 @@ module ActiveRecord::Associations::Builder | |
old_foreign_id = changed_attributes[foreign_key_field] | |
if old_foreign_id | |
- klass = association(#{name.inspect}).klass | |
+ association = association(:#{name}) | |
+ reflection = association.reflection | |
+ if reflection.polymorphic? | |
+ klass = send("#{reflection.foreign_type}_was").constantize | |
+ else | |
+ klass = association.klass | |
+ end | |
old_record = klass.find_by(klass.primary_key => old_foreign_id) | |
if old_record | |
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb | |
index ff1b015..f775608 100644 | |
--- a/activerecord/test/cases/timestamp_test.rb | |
+++ b/activerecord/test/cases/timestamp_test.rb | |
@@ -224,36 +224,62 @@ class TimestampTest < ActiveRecord::TestCase | |
assert_not_equal time, old_pet.updated_at | |
end | |
- def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record | |
- klass = Class.new(ActiveRecord::Base) do | |
- def self.name; 'Toy'; end | |
+ def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record_changes_within_same_class | |
+ car_class = Class.new(ActiveRecord::Base) do | |
+ def self.name; 'Car'; end | |
end | |
- wheel_klass = Class.new(ActiveRecord::Base) do | |
+ wheel_class = Class.new(ActiveRecord::Base) do | |
def self.name; 'Wheel'; end | |
belongs_to :wheelable, :polymorphic => true, :touch => true | |
end | |
- toy1 = klass.find(1) | |
- toy2 = klass.find(2) | |
+ car1 = car_class.find(1) | |
+ car2 = car_class.find(2) | |
- wheel = wheel_klass.new | |
- wheel.wheelable = toy1 | |
- wheel.save! | |
+ wheel = wheel_class.create!(wheelable: car1) | |
time = 3.days.ago.at_beginning_of_hour | |
- toy1.update_columns(updated_at: time) | |
- toy2.update_columns(updated_at: time) | |
+ car1.update_columns(updated_at: time) | |
+ car2.update_columns(updated_at: time) | |
- wheel.wheelable = toy2 | |
+ wheel.wheelable = car2 | |
wheel.save! | |
- toy1.reload | |
- toy2.reload | |
+ assert_not_equal time, car1.reload.updated_at | |
+ assert_not_equal time, car2.reload.updated_at | |
+ end | |
+ | |
+ def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record_changes_with_other_class | |
+ car_class = Class.new(ActiveRecord::Base) do | |
+ def self.name; 'Car'; end | |
+ end | |
+ | |
+ toy_class = Class.new(ActiveRecord::Base) do | |
+ def self.name; 'Toy'; end | |
+ end | |
+ | |
+ wheel_class = Class.new(ActiveRecord::Base) do | |
+ def self.name; 'Wheel'; end | |
+ belongs_to :wheelable, :polymorphic => true, :touch => true | |
+ end | |
+ | |
+ car = car_class.find(1) | |
+ toy = toy_class.find(3) | |
+ | |
+ wheel = wheel_class.create!(wheelable: car) | |
+ | |
+ time = 3.days.ago.at_beginning_of_hour | |
+ | |
+ car.update_columns(updated_at: time) | |
+ toy.update_columns(updated_at: time) | |
+ | |
+ wheel.wheelable = toy | |
+ wheel.save! | |
- assert_not_equal time, toy1.updated_at | |
- assert_not_equal time, toy2.updated_at | |
+ assert_not_equal time, car.reload.updated_at | |
+ assert_not_equal time, toy.reload.updated_at | |
end | |
def test_clearing_association_touches_the_old_record |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment