Rails 3 - check that object is valid with params before update

30,498

Solution 1

To update the attributes without saving them, you can use

@obj.assign_attributes( params[:obj] )

Then to check if the object is valid, you can call

@obj.valid?

If the object is not valid, you can see the errors (only after calling .valid?) by calling

@obj.errors

If the object is valid, you can save it by calling

@obj.save

However, all of this usually isn't necessary. If the object isn't valid, then ActiveRecord won't save the object to the database, so all of the attribute changes are forgotten when you leave the controller action.

Also, since an invalid record won't be saved to the database, you can always just call Object.find() again to get the original object back.

Solution 2

You can call the valid? method to run the validations.

This doesn't guarantee that a subsequent save will succeed if some of your validations depend on the state of other objects in the database. Te save could also fail for reasons unconnected to validations (eg a foreign key constraint)

I'm not sure why you'd want this pattern

Share:
30,498

Related videos on Youtube

ExiRe
Author by

ExiRe

Full stack developer (ruby + vue.js). I also have blog. You can reach me on linkedin: https://www.linkedin.com/pub/sergei-l/58/2a7/833/en

Updated on January 10, 2020

Comments

  • ExiRe
    ExiRe over 4 years

    I have very newbie question. How can i check that object of model is valid with new params BEFORE updating it?

    I want transform that:

    def update
      @obj = SomeModel.find( params[:id] )
    
      if @obj.update_attributes( params[:obj] )
        # That have been updated
      else
        # Ups, errors!
      end
    end
    

    To something like that:

    def update
      @obj = SomeModel.find( params[:id] )
    
      if @obj.valid_with_new_params( params[:obj] )
        @obj.update_attributes( params[:obj] )
      else
        # Ups, errors!
      end
    end
    
  • apneadiving
    apneadiving almost 12 years
    the attributes= method is deprecated in new versions of Rails
  • ExiRe
    ExiRe almost 12 years
    I am saving few objects of different models. So i collect errors of validations of each model and then show it in one popup.
  • Marlin Pierce
    Marlin Pierce almost 12 years
    After @obj.attributes( params[:obj] ), call @obj.save.
  • Gerry
    Gerry almost 12 years
    Thanks @apneadiving didn't know about that :)
  • user664833
    user664833 about 10 years
    The attributes() method as shown in this answer at the time of this writing is deprecated. Instead use assign_attributes(new_attributes) or the alias attributes=(new_attributes). Thus the first line in this answer should be @obj.assign_attributes( params[:obj] ). See ActiveRecord::AttributeAssignment
  • user664833
    user664833 about 10 years
    Re: assign_attributes(new_attributes) -- note that the only attributes set are those named by keys in the params hash. So if you have an existing object, you can add/merge just a subset of attributes.
  • user664833
    user664833 about 10 years
    For the curious, this is straight out of the update(attributes) playbook (which by the way is aliased as update_attributes(attributes)) -- View the source for update(attributes) and you will see assign_attributes(attributes) followed by save (and it's in save that validations happen before actually persisting/saving).
  • Developer
    Developer almost 8 years
    @Justin, not working for me in rails 3.2.22, when i tried to assign the params like @obj.assign_attributes( params[:obj] ) my @obj become nil