diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-04-10 17:43:59 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-04-10 17:44:32 -0300 |
commit | a7a180bd8158a0a2151f0711b874a7495820d6e0 (patch) | |
tree | 826babcdecdf06bda24b56b10543422596d9140c | |
parent | 632d9d22375dd79614ce731eb42875b65112b987 (diff) | |
parent | ec0928076529e8f0b5a4ad58c95cfa1fe6ed5b60 (diff) | |
download | rails-a7a180bd8158a0a2151f0711b874a7495820d6e0.tar.gz rails-a7a180bd8158a0a2151f0711b874a7495820d6e0.tar.bz2 rails-a7a180bd8158a0a2151f0711b874a7495820d6e0.zip |
Merge pull request #12829 from iantropov/issue_insert_via_hmt_scope_3548
Fix insertion of records for hmt association with scope
Conflicts:
activerecord/CHANGELOG.md
-rw-r--r-- | activerecord/CHANGELOG.md | 6 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/has_many_through_association.rb | 6 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 4 | ||||
-rw-r--r-- | activerecord/test/cases/associations/has_many_through_associations_test.rb | 14 | ||||
-rw-r--r-- | activerecord/test/cases/relation_test.rb | 4 | ||||
-rw-r--r-- | activerecord/test/models/club.rb | 2 |
6 files changed, 32 insertions, 4 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 33c6f42988..abf6373030 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,9 @@ +* Fix insertion of records via `has_many :through` association with scope. + + Fixes #3548. + + *Ivan Antropov* + * Auto-generate stable fixture UUIDs on PostgreSQL. Fixes: #11524 diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 64bc98c642..c2eff0d8ce 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -83,12 +83,16 @@ module ActiveRecord @through_records[record.object_id] ||= begin ensure_mutable - through_record = through_association.build + through_record = through_association.build through_scope_attributes through_record.send("#{source_reflection.name}=", record) through_record end end + def through_scope_attributes + scope.where_values_hash(through_association.reflection.name.to_s) + end + def save_through_record(record) build_through_record(record).save! ensure diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 4d37ac6e2b..787f55e2e7 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -529,9 +529,9 @@ module ActiveRecord # # User.where(name: 'Oscar').where_values_hash # # => {name: "Oscar"} - def where_values_hash + def where_values_hash(relation_table_name = table_name) equalities = where_values.grep(Arel::Nodes::Equality).find_all { |node| - node.left.relation.name == table_name + node.left.relation.name == relation_table_name } binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }] diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 026a7fe635..6675e19dd9 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -1102,7 +1102,19 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert_equal [posts(:thinking)], person.reload.first_posts end - def test_has_many_through_with_includes_in_through_association_scope + test "has many through with includes in through association scope" do assert_not_empty posts(:welcome).author_address_extra_with_address end + + test "insert records via has_many_through association with scope" do + club = Club.create! + member = Member.create! + Membership.create!(club: club, member: member) + + club.favourites << member + assert_equal [member], club.favourites + + club.reload + assert_equal [member], club.favourites + end end diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 15611656fd..fb0b906c07 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -16,6 +16,10 @@ module ActiveRecord def self.connection Post.connection end + + def self.table_name + 'fake_table' + end end def test_construction diff --git a/activerecord/test/models/club.rb b/activerecord/test/models/club.rb index 566e0873f1..a762ad4bb5 100644 --- a/activerecord/test/models/club.rb +++ b/activerecord/test/models/club.rb @@ -6,6 +6,8 @@ class Club < ActiveRecord::Base has_one :sponsored_member, :through => :sponsor, :source => :sponsorable, :source_type => "Member" belongs_to :category + has_many :favourites, -> { where(memberships: { favourite: true }) }, through: :memberships, source: :member + private def private_method |