diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 29e2e2cedc87a..2876bae302bc3 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -1114,7 +1114,7 @@ def build_joins(manager, joins, aliases) else join end - end.compact_blank! + end.compact_blank!.uniq! while joins.first.is_a?(Arel::Nodes::Join) join_node = joins.shift @@ -1144,8 +1144,8 @@ def build_joins(manager, joins, aliases) def build_join_query(manager, buckets, join_type, aliases) association_joins = buckets[:association_join] stashed_joins = buckets[:stashed_join] - leading_joins = buckets[:leading_join].tap(&:uniq!) - join_nodes = buckets[:join_node].tap(&:uniq!) + leading_joins = buckets[:leading_join] + join_nodes = buckets[:join_node] join_sources = manager.join_sources join_sources.concat(leading_joins) unless leading_joins.empty? diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb index b65af4b819341..166a59ec7b271 100644 --- a/activerecord/test/cases/associations/inner_join_association_test.rb +++ b/activerecord/test/cases/associations/inner_join_association_test.rb @@ -69,6 +69,16 @@ def test_user_supplied_joins_order_should_be_preserved assert_equal [expected], Person.joins(string_join).joins(agents.create_join(agents, agents.create_on(constraint))) end + def test_deduplicate_joins + posts = Post.arel_table + constraint = posts[:author_id].eq(Author.arel_attribute(:id)) + + authors = Author.joins(posts.create_join(posts, posts.create_on(constraint))) + authors = authors.joins(:author_address).merge(authors.where("posts.type": "SpecialPost")) + + assert_equal [authors(:david)], authors + end + def test_construct_finder_sql_ignores_empty_joins_hash sql = Author.joins({}).to_sql assert_no_match(/JOIN/i, sql)