Skip to content

Commit cf99be4

Browse files
authored
Merge pull request rails#43192 from dylanahsmith/ar-relation-update-bang
Avoid scoping update transaction when calling update! on a relation
2 parents a8c4c27 + de7ca90 commit cf99be4

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

activerecord/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
* Avoid scoping update callbacks in `ActiveRecord::Relation#update!`.
2+
3+
Making it consistent with how scoping is applied only to the query in `ActiveRecord::Relation#update`
4+
and not also to the callbacks from the update itself.
5+
6+
*Dylan Thacker-Smith*
7+
18
* Fix 2 cases that inferred polymorphic class from the association's `foreign_type`
29
using `String#constantize` instead of the model's `polymorphic_class_for`.
310

activerecord/lib/active_record/relation.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,14 @@ def update(id = :all, attributes) # :nodoc:
498498
end
499499
end
500500

501+
def update!(id = :all, attributes) # :nodoc:
502+
if id == :all
503+
each { |record| record.update!(attributes) }
504+
else
505+
klass.update!(id, attributes)
506+
end
507+
end
508+
501509
# Updates the counters of the records in the current relation.
502510
#
503511
# ==== Parameters

activerecord/test/cases/relation/update_all_test.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,24 @@ def test_update_on_relation_passing_active_record_object_is_not_permitted
173173
end
174174
end
175175

176+
def test_update_bang_on_relation
177+
topic1 = TopicWithCallbacks.create! title: "arel", author_name: nil
178+
topic2 = TopicWithCallbacks.create! title: "activerecord", author_name: nil
179+
topic3 = TopicWithCallbacks.create! title: "ar", author_name: nil
180+
topics = TopicWithCallbacks.where(id: [topic1.id, topic2.id])
181+
topics.update!(title: "adequaterecord")
182+
183+
assert_equal TopicWithCallbacks.count, TopicWithCallbacks.topic_count
184+
185+
assert_equal "adequaterecord", topic1.reload.title
186+
assert_equal "adequaterecord", topic2.reload.title
187+
assert_equal "ar", topic3.reload.title
188+
# Testing that the before_update callbacks have run
189+
assert_equal "David", topic1.reload.author_name
190+
assert_equal "David", topic2.reload.author_name
191+
assert_nil topic3.reload.author_name
192+
end
193+
176194
def test_update_all_cares_about_optimistic_locking
177195
david = people(:david)
178196

0 commit comments

Comments
 (0)