Skip to content

Commit f1cc222

Browse files
committed
Preserve custom predicate handlers for joins
Otherwise join queries doesn't recognize the registered custom predicate handlers for the original class.
1 parent 3deec36 commit f1cc222

File tree

5 files changed

+17
-5
lines changed

5 files changed

+17
-5
lines changed

activerecord/lib/active_record/reflection.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def scopes
198198
end
199199

200200
def join_scope(table, foreign_table, foreign_klass)
201-
predicate_builder = PredicateBuilder.new(TableMetadata.new(klass, table))
201+
predicate_builder = klass.predicate_builder.with(TableMetadata.new(klass, table))
202202
scope_chain_items = join_scopes(table, predicate_builder)
203203
klass_scope = klass_join_scope(table, predicate_builder)
204204

activerecord/lib/active_record/relation.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def exec_explain(&block)
7676

7777
def initialize(model, table: nil, predicate_builder: nil, values: {})
7878
if table
79-
predicate_builder ||= PredicateBuilder.new(TableMetadata.new(model, table))
79+
predicate_builder ||= model.predicate_builder.with(TableMetadata.new(model, table))
8080
else
8181
table = model.arel_table
8282
predicate_builder ||= model.predicate_builder

activerecord/lib/active_record/relation/predicate_builder.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,15 @@ def resolve_arel_attribute(table_name, column_name, &block)
7272
table.associated_table(table_name, &block).arel_table[column_name]
7373
end
7474

75+
def with(table)
76+
other = dup
77+
other.table = table
78+
other
79+
end
80+
7581
protected
82+
attr_writer :table
83+
7684
def expand_from_hash(attributes, &block)
7785
return ["1=0"] if attributes.empty?
7886

activerecord/lib/active_record/table_metadata.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ def reflect_on_aggregation(aggregation_name)
6969

7070
def predicate_builder
7171
if klass
72-
predicate_builder = klass.predicate_builder.dup
73-
predicate_builder.instance_variable_set(:@table, self)
74-
predicate_builder
72+
klass.predicate_builder.with(self)
7573
else
7674
PredicateBuilder.new(self)
7775
end

activerecord/test/cases/relation/predicate_builder_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ def test_registering_new_handlers_for_association
2323
assert_match %r{#{Regexp.escape(quote_table_name("topics.title"))} ~ 'rails'}i, Reply.joins(:topic).where(topics: { title: /rails/ }).to_sql
2424
end
2525

26+
def test_registering_new_handlers_for_joins
27+
Reply.belongs_to :regexp_topic, -> { where(title: /rails/) }, class_name: "Topic", foreign_key: "parent_id"
28+
29+
assert_match %r{#{Regexp.escape(quote_table_name("regexp_topic.title"))} ~ 'rails'}i, Reply.joins(:regexp_topic).references(Arel.sql("regexp_topic")).to_sql
30+
end
31+
2632
def test_references_with_schema
2733
assert_equal %w{schema.table}, ActiveRecord::PredicateBuilder.references(%w{schema.table.column})
2834
end

0 commit comments

Comments
 (0)