From c6a62dc327c54baec87306f5c381e13cacc00a19 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Mon, 4 Jul 2016 06:18:37 +0900 Subject: Do not handle as an associated predicate if a table has the column If handled as an associated predicate even though a table has the column, will generate invalid SQL by valid column name treated as a table name. --- activerecord/lib/active_record/relation/predicate_builder.rb | 4 ++-- activerecord/lib/active_record/table_metadata.rb | 4 ++++ activerecord/test/cases/finder_test.rb | 4 ++-- activerecord/test/cases/relation/where_test.rb | 2 +- activerecord/test/cases/serialized_attribute_test.rb | 7 +++++++ 5 files changed, 16 insertions(+), 5 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 0c8282de8e..780a1ee422 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -74,7 +74,7 @@ module ActiveRecord return ["1=0"] if attributes.empty? attributes.flat_map do |key, value| - if value.is_a?(Hash) + if value.is_a?(Hash) && !table.has_column?(key) associated_predicate_builder(key).expand_from_hash(value) else build(table.arel_attribute(key), value) @@ -88,7 +88,7 @@ module ActiveRecord attributes.each do |column_name, value| case - when value.is_a?(Hash) + when value.is_a?(Hash) && !table.has_column?(column_name) attrs, bvs = associated_predicate_builder(column_name).create_binds_for_hash(value) result[column_name] = attrs binds += bvs diff --git a/activerecord/lib/active_record/table_metadata.rb b/activerecord/lib/active_record/table_metadata.rb index e8d6a144f9..0ca880e635 100644 --- a/activerecord/lib/active_record/table_metadata.rb +++ b/activerecord/lib/active_record/table_metadata.rb @@ -37,6 +37,10 @@ module ActiveRecord end end + def has_column?(column_name) + klass && klass.columns_hash.key?(column_name.to_s) + end + def associated_with?(association_name) klass && klass._reflect_on_association(association_name) end diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index f8f9f2d383..85b6b0da0e 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -22,13 +22,13 @@ class FinderTest < ActiveRecord::TestCase fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :author_addresses, :customers, :categories, :categorizations, :cars def test_find_by_id_with_hash - assert_raises(ActiveRecord::StatementInvalid) do + assert_nothing_raised do Post.find_by_id(limit: 1) end end def test_find_by_title_and_id_with_hash - assert_raises(ActiveRecord::StatementInvalid) do + assert_nothing_raised do Post.find_by_title_and_id("foo", limit: 1) end end diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb index ad9008ea4d..ce4e041793 100644 --- a/activerecord/test/cases/relation/where_test.rb +++ b/activerecord/test/cases/relation/where_test.rb @@ -196,7 +196,7 @@ module ActiveRecord end def test_where_error - assert_raises(ActiveRecord::StatementInvalid) do + assert_nothing_raised do Post.where(id: { "posts.author_id" => 10 }).first end end diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb index ceb0d5441b..bebd856faf 100644 --- a/activerecord/test/cases/serialized_attribute_test.rb +++ b/activerecord/test/cases/serialized_attribute_test.rb @@ -157,6 +157,13 @@ class SerializedAttributeTest < ActiveRecord::TestCase assert_equal(settings, Topic.find(topic.id).content) end + def test_where_by_serialized_attribute_with_hash + settings = { "color" => "green" } + Topic.serialize(:content, Hash) + topic = Topic.create!(content: settings) + assert_equal topic, Topic.where(content: settings).take + end + def test_serialized_default_class Topic.serialize(:content, Hash) topic = Topic.new -- cgit v1.2.3