Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between update and update_attributes

In Rails 5, what is the difference between update and update_attributes methods. I'm seeing the following results for both the methods

  1. Returns true/false
  2. Checking for active record validation
  3. Call backs are triggered

and also regarding update method a new thing was introduced in active record relation. I'm not able to understand it. What is the difference?

Moreover are we using update_attributes in Rails 5. It's not there in active record documentation.

I'm confused with all update methods. I need clarity

like image 827
Sam Avatar asked Dec 18 '18 09:12

Sam


People also ask

What is difference between update update_attributes?

All of these will update an object in a database without having to explicitly tell AR to update. update_attribute can update only one column. Use update_attribute to skip validations. update_attribute uses save(false) while update_attributes uses save (which means save(true)).

What is update_ attributes in Rails?

update(name: "Rob") This method used to be called update_attributes in Rails 3. It changes the attributes of the model, checks the validations, and updates the record in the database if it validates. Note that just like update_attribute this method also saves other changed attributes to the database.


2 Answers

As of Rails 4.0.2, #update returns false if the update failed. Before Rails 4.0.2, #update returned the object that got updated. The main difference therefore was the return value. After this change, #update_attributes is just an alias of #update. It seems there are talks to deprecate #update_attributes in Rails 6 which is not released yet.

  • https://github.com/rails/rails/pull/31998
  • https://github.com/rails/rails/commit/5645149d3a27054450bd1130ff5715504638a5f5
like image 104
stcho Avatar answered Oct 20 '22 18:10

stcho


From the rails 5 files it seems to me update can be used to update multiple objects(array of records) but update_attributes only work on single records otherwise both are same

From rails core files for update_attributes:

Updates a single attribute and saves the record. This is especially useful for boolean flags on existing records. Also note that

  • Validation is skipped.
  • \Callbacks are invoked.
  • updated_at/updated_on column is updated if that column is available.
  • Updates all the attributes that are dirty in this object.

This method raises an ActiveRecord::ActiveRecordError if the attribute is marked as readonly.

def update_attribute(name, value)
  name = name.to_s
  verify_readonly_attribute(name)
  public_send("#{name}=", value)

  save(validate: false)
end

For Update

Updates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.

==== Parameters

  • +id+ - This should be the id or an array of ids to be updated.
  • +attributes+ - This should be a hash of attributes or an array of hashes.

==== Examples

# Updates one record Person.update(15, user_name: "Samuel", group: "expert")

# Updates multiple records people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } } Person.update(people.keys, people.values)

# 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 an UPDATE query for each record, which may cause a performance issue. When running callbacks is not needed for each record update, it is preferred to use {update_all}[rdoc-ref:Relation#update_all] for updating all records in a single query.

def update(id, attributes)
  if id.is_a?(Array)
    id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
      object.update(attributes[idx])
    }
  else
    if ActiveRecord::Base === id
      raise ArgumentError,
        "You are passing an instance of ActiveRecord::Base to `update`. " \
        "Please pass the id of the object by calling `.id`."
    end
    object = find(id)
    object.update(attributes)
    object
  end
end
like image 27
Thorin Avatar answered Oct 20 '22 18:10

Thorin