提交 1d316ac1 编写于 作者: N Nat Budin

Make filter_binds filter out symbols that are equal to strings

ActiveRecord::Relation::Merger's filter_binds method does not filter out bind
variables when one of the attribute nodes has a string name, but the other has
a symbol name, even when those names are actually equal.

This can result in there being more bind variables than placeholders in the
generated SQL.  This is particularly an issue for PostgreSQL, where this is
treated as an error.

This patch changes the filter_binds method to make it convert both attribute
names to strings before comparing.
上级 eacb4264
* `ActiveRecord::Relation::Merger#filter_binds` now compares equivalent symbols and
strings in column names as equal.
This fixes a rare case in which more bind values are passed than there are
placeholders for them in the generated SQL statement, which can make PostgreSQL
throw a `StatementInvalid` exception.
*Nat Budin*
* `change_column_default` allows `[]` as argument to `change_column_default`.
Fixes #11586.
......
......@@ -156,7 +156,7 @@ def merge_single_values
def filter_binds(lhs_binds, removed_wheres)
return lhs_binds if removed_wheres.empty?
set = Set.new removed_wheres.map { |x| x.left.name }
set = Set.new removed_wheres.map { |x| x.left.name.to_s }
lhs_binds.dup.delete_if { |col,_| set.include? col.name }
end
......
......@@ -108,6 +108,11 @@ def test_merging_reorders_bind_params
merged = left.merge(right)
assert_equal post, merged.first
end
def test_merging_compares_symbols_and_strings_as_equal
post = PostThatLoadsCommentsInAnAfterSaveHook.create!(title: "First Post", body: "Blah blah blah.")
assert_equal "First comment!", post.comments.where(body: "First comment!").first_or_create.body
end
end
class MergingDifferentRelationsTest < ActiveRecord::TestCase
......
......@@ -40,3 +40,11 @@ class SubSpecialComment < SpecialComment
class VerySpecialComment < Comment
end
class CommentThatAutomaticallyAltersPostBody < Comment
belongs_to :post, class_name: "PostThatLoadsCommentsInAnAfterSaveHook", foreign_key: :post_id
after_save do |comment|
comment.post.update_attributes(body: "Automatically altered")
end
end
\ No newline at end of file
......@@ -208,3 +208,12 @@ class SpecialPostWithDefaultScope < ActiveRecord::Base
self.table_name = 'posts'
default_scope { where(:id => [1, 5,6]) }
end
class PostThatLoadsCommentsInAnAfterSaveHook < ActiveRecord::Base
self.table_name = 'posts'
has_many :comments, class_name: "CommentThatAutomaticallyAltersPostBody", foreign_key: :post_id
after_save do |post|
post.comments.load
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册