Method: ActiveRecord::Relation#update_all
- Defined in:
- lib/active_record/relation.rb
#update_all(updates) ⇒ Object
Updates all records in the current relation with details given. This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks or validations. However, values passed to #update_all will still go through Active Record’s normal type casting and serialization. Returns the number of rows affected.
Note: As Active Record callbacks are not triggered, this method will not automatically update updated_at/updated_on columns.
Parameters
-
updates- A string, array, or hash representing the SET part of an SQL statement. Any strings provided will be type cast, unless you useArel.sql. (Don’t pass user-provided values toArel.sql.)
Examples
# Update all customers with the given attributes
Customer.update_all wants_email: true
# Update all books with 'Rails' in their title
Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')
# Update all books that match conditions, but limit it to 5 ordered by date
Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(author: 'David')
# Update all invoices and set the number column to its id value.
Invoice.update_all('number = id')
# Update all books with 'Rails' in their title
Book.where('title LIKE ?', '%Rails%').update_all(title: Arel.sql("title + ' - volume 1'"))
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
# File 'lib/active_record/relation.rb', line 598 def update_all(updates) raise ArgumentError, "Empty list of attributes to change" if updates.blank? return 0 if @none invalid_methods = INVALID_METHODS_FOR_UPDATE_AND_DELETE_ALL.select do |method| value = @values[method] method == :distinct ? value : value&.any? end if invalid_methods.any? ActiveRecord.deprecator.warn <<~MESSAGE `#{invalid_methods.join(', ')}` is not supported by `update_all` and was never included in the generated query. Calling `#{invalid_methods.join(', ')}` with `update_all` will raise an error in Rails 8.2. MESSAGE end if updates.is_a?(Hash) if model.locking_enabled? && !updates.key?(model.locking_column) && !updates.key?(model.locking_column.to_sym) attr = table[model.locking_column] updates[attr.name] = _increment_attribute(attr) end values = _substitute_values(updates) else values = Arel.sql(model.sanitize_sql_for_assignment(updates, table.name)) end model.with_connection do |c| arel = eager_loading? ? apply_join_dependency.arel : arel() arel.source.left = table key = if model.composite_primary_key? primary_key.map { |pk| table[pk] } else table[primary_key] end stmt = arel.compile_update(values, key) c.update(stmt, "#{model} Update All").tap { reset } end end |