Skip to content

Commit e7bc5d2

Browse files
authored
Merge pull request rails#51407 from fatkodima/wrap-expressions-in-update_all
Wrap by parentheses custom complex sql literals in `update_all`
2 parents 68b20b6 + fa2aea8 commit e7bc5d2

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

activerecord/lib/active_record/relation.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,11 @@ def _scoping(scope, registry, all_queries = false)
10231023
def _substitute_values(values)
10241024
values.map do |name, value|
10251025
attr = table[name]
1026-
unless Arel.arel_node?(value)
1026+
if Arel.arel_node?(value)
1027+
if value.is_a?(Arel::Nodes::SqlLiteral)
1028+
value = Arel::Nodes::Grouping.new(value)
1029+
end
1030+
else
10271031
type = klass.type_for_attribute(attr.name)
10281032
value = predicate_builder.build_bind_attribute(attr.name, type.cast(value))
10291033
end

activerecord/test/cases/persistence_test.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
require "models/minimalistic"
1818
require "models/parrot"
1919
require "models/minivan"
20+
require "models/car"
2021
require "models/person"
2122
require "models/ship"
2223
require "models/admin"
@@ -29,7 +30,7 @@
2930

3031
class PersistenceTest < ActiveRecord::TestCase
3132
fixtures :topics, :companies, :developers, :accounts, :minimalistics, :authors, :author_addresses,
32-
:posts, :minivans, :clothing_items, :cpk_books
33+
:posts, :minivans, :clothing_items, :cpk_books, :people, :cars
3334

3435
def test_populates_non_primary_key_autoincremented_column
3536
topic = TitlePrimaryKeyTopic.create!(title: "title pk topic")
@@ -908,6 +909,16 @@ def test_update_all_with_hash
908909
assert_nil Topic.find(2).last_read
909910
end
910911

912+
def test_update_all_with_custom_sql_as_value
913+
person = people(:michael)
914+
person.update!(cars_count: 0)
915+
916+
Person.update_all(cars_count: Arel.sql(<<~SQL))
917+
select count(*) from cars where cars.person_id = people.id
918+
SQL
919+
assert_equal 1, person.reload.cars_count
920+
end
921+
911922
def test_delete_new_record
912923
client = Client.new(name: "37signals")
913924
client.delete

0 commit comments

Comments
 (0)