1
0
Fork 0
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:
Ryuta Kamizono 2020-02-13 11:47:53 +09:00 committed by GitHub
commit ac7eee44f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 10 deletions

View file

@ -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)

View file

@ -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

View file

@ -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