1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #41319 from kamipo/fix_scoping_to_take_only_equality

Fix `scope_for_create` to take only equality nodes
This commit is contained in:
Ryuta Kamizono 2021-02-09 21:31:53 +09:00 committed by GitHub
commit cc9814cd19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 7 deletions

View file

@ -687,8 +687,7 @@ module ActiveRecord
end
def scope_for_create
hash = where_values_hash
hash.delete(klass.inheritance_column) if klass.finder_needs_type_condition?
hash = where_clause.to_h(klass.table_name, equality_only: true)
create_with_value.each { |k, v| hash[k.to_s] = v } unless create_with_value.empty?
hash
end

View file

@ -58,8 +58,8 @@ module ActiveRecord
end
end
def to_h(table_name = nil)
equalities(predicates).each_with_object({}) do |node, hash|
def to_h(table_name = nil, equality_only: false)
equalities(predicates, equality_only).each_with_object({}) do |node, hash|
next if table_name&.!= node.left.relation.name
name = node.left.name.to_s
value = extract_node_value(node.right)
@ -134,14 +134,14 @@ module ActiveRecord
attr_node
end
def equalities(predicates)
def equalities(predicates, equality_only)
equalities = []
predicates.each do |node|
if equality_node?(node)
if equality_only ? Arel::Nodes::Equality === node : equality_node?(node)
equalities << node
elsif node.is_a?(Arel::Nodes::And)
equalities.concat equalities(node.children)
equalities.concat equalities(node.children, equality_only)
end
end

View file

@ -212,6 +212,26 @@ class RelationScopingTest < ActiveRecord::TestCase
assert_includes Post.find(1).comments, new_comment
end
def test_scoped_create_with_where_with_array
new_comment = VerySpecialComment.where(label: [0, 1], post_id: 1).scoping do
VerySpecialComment.create body: "Wonderful world"
end
assert_equal 1, new_comment.post_id
assert_equal "default", new_comment.label
assert_includes Post.find(1).comments, new_comment
end
def test_scoped_create_with_where_with_range
new_comment = VerySpecialComment.where(label: 0..1, post_id: 1).scoping do
VerySpecialComment.create body: "Wonderful world"
end
assert_equal 1, new_comment.post_id
assert_equal "default", new_comment.label
assert_includes Post.find(1).comments, new_comment
end
def test_scoped_create_with_create_with
new_comment = VerySpecialComment.create_with(post_id: 1).scoping do
VerySpecialComment.create body: "Wonderful world"