Search code examples
ruby-on-railscallbackupdate-attributes

Rails: #update_attribute vs #update_attributes


obj.update_attribute(:only_one_field, 'Some Value')
obj.update_attributes(field1: 'value', field2: 'value2', field3: 'value3')

Both of these will update an object without having to explicitly tell ActiveRecord to update.

Rails API says:

update_attribute

Updates a single attribute and saves the record without going through the normal validation procedure. This is especially useful for boolean flags on existing records. The regular update_attribute method in Base is replaced with this when the validations module is mixed in, which it is by default.

update_attributes

Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will fail and false will be returned.

So if I don't want to have the object validated I should use #update_attribute. What if I have this update on a #before_save, will it stackoverflow?

My question is does #update_attribute also bypass the before save or just the validation.

Also, what is the correct syntax to pass a hash to #update_attributes ... check out my example at the top.


Solution

  • Please refer to update_attribute. On clicking show source you will get following code

          # File vendor/rails/activerecord/lib/active_record/base.rb, line 2614
    2614:       def update_attribute(name, value)
    2615:         send(name.to_s + '=', value)
    2616:         save(false)
    2617:       end
    

    and now refer update_attributes and look at its code you get

          # File vendor/rails/activerecord/lib/active_record/base.rb, line 2621
    2621:       def update_attributes(attributes)
    2622:         self.attributes = attributes
    2623:         save
    2624:       end
    

    the difference between two is update_attribute uses save(false) whereas update_attributes uses save or you can say save(true).

    Sorry for the long description but what I want to say is important. save(perform_validation = true), if perform_validation is false it bypasses (skips will be the proper word) all the validations associated with save.

    For second question

    Also, what is the correct syntax to pass a hash to update_attributes... check out my example at the top.

    Your example is correct.

    Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")
    

    or

    Object.update_attributes :field1 => "value", :field2 => "value2", :field3 => "value3"
    

    or if you get all fields data & name in a hash say params[:user] here use just

    Object.update_attributes(params[:user])