From 431f8e01196044877c2acea4271410b1033ec915 Mon Sep 17 00:00:00 2001 From: Agis- Date: Tue, 15 Jul 2014 03:25:18 +0300 Subject: Only merge scopes with zero arity in has_many through with dynamic conditions. Fixes #16128 This bug was introduced in https://github.com/rails/rails/commit/c35e438620f2d56562251571377995359546393d so it's present from 4.1.2-rc1 and after. https://github.com/rails/rails/commit/c35e438620f2d56562251571377995359546393d merges any relation scopes passed as proc objects to the relation, but does *not* take into account the arity of the lambda. To reproduce: https://gist.github.com/Agis-/5f1f0d664d2cd08dfb9b --- activerecord/CHANGELOG.md | 7 +++++++ .../lib/active_record/associations/through_association.rb | 6 +++++- activerecord/test/cases/relation/merging_test.rb | 13 +++++++++++++ activerecord/test/models/comment.rb | 1 + activerecord/test/models/developer.rb | 2 ++ activerecord/test/schema/schema.rb | 1 + 6 files changed, 29 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 74f802f3f7..c2e79e9f02 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,10 @@ +* Fix has_many :through relation merging failing when dynamic conditions are + passed as a lambda with an arity of one. + + Fixes #16128 + + *Agis Anastasopoulos* + * Fixed the `Relation#exists?` to work with polymorphic associations. Fixes #15821. diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb index 611d471e62..e47e81aa0f 100644 --- a/activerecord/lib/active_record/associations/through_association.rb +++ b/activerecord/lib/active_record/associations/through_association.rb @@ -15,7 +15,11 @@ module ActiveRecord scope = super reflection.chain.drop(1).each do |reflection| relation = reflection.klass.all - relation.merge!(reflection.scope) if reflection.scope + + reflection_scope = reflection.scope + if reflection_scope && reflection_scope.arity.zero? + relation.merge!(reflection_scope) + end scope.merge!( relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load) diff --git a/activerecord/test/cases/relation/merging_test.rb b/activerecord/test/cases/relation/merging_test.rb index 2b5c2fd5a4..54a581e416 100644 --- a/activerecord/test/cases/relation/merging_test.rb +++ b/activerecord/test/cases/relation/merging_test.rb @@ -4,6 +4,7 @@ require 'models/comment' require 'models/developer' require 'models/post' require 'models/project' +require 'models/rating' class RelationMergingTest < ActiveRecord::TestCase fixtures :developers, :comments, :authors, :posts @@ -144,4 +145,16 @@ class MergingDifferentRelationsTest < ActiveRecord::TestCase assert_equal ["Mary", "Mary", "Mary", "David"], posts_by_author_name end + + test "relation merging (using a proc argument)" do + dev = Developer.where(name: "Jamis").first + + comment_1 = dev.comments.create!(body: "I'm Jamis", post: Post.first) + rating_1 = comment_1.ratings.create! + + comment_2 = dev.comments.create!(body: "I'm John", post: Post.first) + rating_2 = comment_2.ratings.create! + + assert_equal dev.ratings, [rating_1] + end end diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb index 15970758db..7a88299d08 100644 --- a/activerecord/test/models/comment.rb +++ b/activerecord/test/models/comment.rb @@ -9,6 +9,7 @@ class Comment < ActiveRecord::Base belongs_to :post, :counter_cache => true belongs_to :author, polymorphic: true belongs_to :resource, polymorphic: true + belongs_to :developer has_many :ratings diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 5bd2f00129..3627cfdd09 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -46,6 +46,8 @@ class Developer < ActiveRecord::Base has_many :audit_logs has_many :contracts has_many :firms, :through => :contracts, :source => :firm + has_many :comments, ->(developer) { where(body: "I'm #{developer.name}") } + has_many :ratings, through: :comments scope :jamises, -> { where(:name => 'Jamis') } diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 98f2492ef8..0584df87c6 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -198,6 +198,7 @@ ActiveRecord::Schema.define do t.references :author, polymorphic: true t.string :resource_id t.string :resource_type + t.integer :developer_id end create_table :companies, force: true do |t| -- cgit v1.2.3