mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #38438 from kamipo/fix_association_query_with_custom_handler
Registered predicate handler should be used for association queries
This commit is contained in:
commit
ac7eee44f0
3 changed files with 34 additions and 10 deletions
|
@ -67,7 +67,7 @@ module ActiveRecord
|
|||
|
||||
attributes.flat_map do |key, value|
|
||||
if value.is_a?(Hash) && !table.has_column?(key)
|
||||
associated_predicate_builder(key).expand_from_hash(value)
|
||||
table.associated_predicate_builder(key).expand_from_hash(value)
|
||||
elsif table.associated_with?(key)
|
||||
# Find the foreign key when using queries such as:
|
||||
# Post.where(author: author)
|
||||
|
@ -114,10 +114,6 @@ module ActiveRecord
|
|||
private
|
||||
attr_reader :table
|
||||
|
||||
def associated_predicate_builder(association_name)
|
||||
self.class.new(table.associated_table(association_name))
|
||||
end
|
||||
|
||||
def convert_dot_notation_to_hash(attributes)
|
||||
dot_notation = attributes.select do |k, v|
|
||||
k.include?(".") && !v.is_a?(Hash)
|
||||
|
|
|
@ -57,6 +57,10 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def associated_predicate_builder(table_name)
|
||||
associated_table(table_name).predicate_builder
|
||||
end
|
||||
|
||||
def polymorphic_association?
|
||||
association && association.polymorphic?
|
||||
end
|
||||
|
@ -69,6 +73,17 @@ module ActiveRecord
|
|||
klass.reflect_on_aggregation(aggregation_name)
|
||||
end
|
||||
|
||||
protected
|
||||
def predicate_builder
|
||||
if klass
|
||||
predicate_builder = klass.predicate_builder.dup
|
||||
predicate_builder.instance_variable_set(:@table, self)
|
||||
predicate_builder
|
||||
else
|
||||
PredicateBuilder.new(self)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
attr_reader :klass, :types, :arel_table, :association
|
||||
end
|
||||
|
|
|
@ -1,18 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "cases/helper"
|
||||
require "models/topic"
|
||||
require "models/reply"
|
||||
|
||||
module ActiveRecord
|
||||
class PredicateBuilderTest < ActiveRecord::TestCase
|
||||
def test_registering_new_handlers
|
||||
def setup
|
||||
Topic.predicate_builder.register_handler(Regexp, proc do |column, value|
|
||||
Arel::Nodes::InfixOperation.new("~", column, Arel.sql(value.source))
|
||||
Arel::Nodes::InfixOperation.new("~", column, Arel::Nodes.build_quoted(value.source))
|
||||
end)
|
||||
end
|
||||
|
||||
assert_match %r{["`]topics["`]\.["`]title["`] ~ rails}i, Topic.where(title: /rails/).to_sql
|
||||
ensure
|
||||
def teardown
|
||||
Topic.reset_column_information
|
||||
end
|
||||
|
||||
def test_registering_new_handlers
|
||||
assert_match %r{#{Regexp.escape(topic_title)} ~ 'rails'}i, Topic.where(title: /rails/).to_sql
|
||||
end
|
||||
|
||||
def test_registering_new_handlers_for_association
|
||||
assert_match %r{#{Regexp.escape(topic_title)} ~ 'rails'}i, Reply.joins(:topic).where(topics: { title: /rails/ }).to_sql
|
||||
end
|
||||
|
||||
private
|
||||
def topic_title
|
||||
Topic.connection.quote_table_name("topics.title")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue