aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation.rb
diff options
context:
space:
mode:
authorPrathamesh Sonpatki <csonpatki@gmail.com>2013-08-15 12:43:25 +0530
committerPrathamesh Sonpatki <csonpatki@gmail.com>2014-12-20 15:33:18 +0530
commit5ef713c53c49b54615be9b5a400ac5810b404e76 (patch)
tree9fd3b9b5155ce349ae2e31dbc59ea681e9983f27 /activerecord/lib/active_record/relation.rb
parent79b71da793f100a6311861a4bc2e7cb0815ff28e (diff)
downloadrails-5ef713c53c49b54615be9b5a400ac5810b404e76.tar.gz
rails-5ef713c53c49b54615be9b5a400ac5810b404e76.tar.bz2
rails-5ef713c53c49b54615be9b5a400ac5810b404e76.zip
Allow ActiveRecord::Relation#update to run on result of a relation with callbacks and validations
- Right now, there is no method to update multiple records with validations and callbacks. - Changed the behavior of existing `update` method so that when `id` attribute is not given and the method is called on an `Relation` object, it will execute update for every record of the `Relation` and will run validations and callbacks for every record. - Added test case for validating that the callbacks run when `update` is called on a `Relation`. - Changed test_create_columns_not_equal_attributes test from persistence_test to include author_name column on topics table as it it used in before_update callback. - This change introduces performance issues when a large number of records are to be updated because it runs UPDATE query for every record of the result. The `update_all` method can be used in that case if callbacks are not required because it will only run single UPDATE for all the records.
Diffstat (limited to 'activerecord/lib/active_record/relation.rb')
-rw-r--r--activerecord/lib/active_record/relation.rb14
1 files changed, 13 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index daafb0b645..5ca28033bf 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -362,9 +362,21 @@ module ActiveRecord
# # Updates multiple records
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
# Person.update(people.keys, people.values)
- def update(id, attributes)
+ #
+ # # Updates multiple records from the result of a relation
+ # people = Person.where(group: 'expert')
+ # people.update(group: 'masters')
+ #
+ # Note: Updating a large number of records will run a
+ # UPDATE query for each record, which may cause a performance
+ # issue. So if it is not needed to run callbacks for each update, it is
+ # preferred to use <tt>update_all</tt> for updating all records using
+ # a single query.
+ def update(id = :all, attributes)
if id.is_a?(Array)
id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) }
+ elsif id == :all
+ to_a.each { |record| record.update(attributes) }
else
object = find(id)
object.update(attributes)