Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why/ when to check for Object.persisted? versus Object.save

I'm just trying to understand two patterns that I've seen in Ruby code.

In Michael Hartl's standard tutorial, the code is as such:

def create
  @user = User.new(params[:user])
  if @user.save
    sign_in @user
    flash[:success] = "Welcome to the Sample App!"
    redirect_to @user
  else
    render 'new'
  end
end

This is the pattern I'm very used to. I just implemented Devise, and its pattern however, is this:

def create
  build_resource(sign_up_params)

  resource.save
  yield resource if block_given?
  if resource.persisted?
    if resource.active_for_authentication?
      set_flash_message :notice, :signed_up if is_flashing_format?
      sign_up(resource_name, resource)
      respond_with resource, location: after_sign_up_path_for(resource)
    else
      set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
      expire_data_after_sign_in!
      respond_with resource, location: after_inactive_sign_up_path_for(resource)
    end
  else
    clean_up_passwords resource
    set_minimum_password_length
    respond_with resource
  end
end

Why is devise checking for resource.persisted? in the if statement as opposed to resource.save? And when might you want to use one over the other?

Thanks!

like image 553
james Avatar asked Jul 07 '15 18:07

james


2 Answers

The reason it is written this way in Devise is because they want to call yield between the save and the rest of the function. So they cannot use the if resource.save, and instead check if the call to save succeeded using the persisted? call.

On what does yield ... if block_given? do, Ruby " yield row if block_given?" gives a good explanation.

like image 20
Qortex Avatar answered Sep 22 '22 16:09

Qortex


Object#persisted? checks whether an object is present in database or not.

Object#save makes changes to the database, returning true or false depending on the result of the operation, and including error messages to that active record object when it fails.

Example A

Successfully saving a new record will make it persistent:

if new_object.save
  # It's successfully saved (and persisted)
  assert new_object.persisted?
else
  # It's not saved, therefore not persisted
   assert_not new_object.persisted? 
end

Example B

Saving an existing record (edit it) will not change its persistence:

# The record is already in the DB, so it is persisted
assert record.persisted?

if record.save
  # update succeeded
else
  # update failed 
end

assert record.persisted?
like image 97
Rubyrider Avatar answered Sep 18 '22 16:09

Rubyrider