Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update attributes for User only if attributes have changed

The original, happily working version of my project looked like this:

1) User fills out form (new action) and hits submit (create action)

2) User is redirected to their edit page (edit action uses an edit_id created by model, not Rails auto-gen id), which shows the info user had already submitted

3) User can choose to change info (update action) and re-submit

In this version, even if the user changes nothing in the edit page and submits, the page will still flash a success alert.

From a database perspective, I don’t really care, because since the form is prefilled with the user’s info, the update_attributes method is just overriding old info with the same info.

From a user perspective though, it's annoying, so I want to ensure that the info is only updated and the success alert flashed only if the user actually changes something.

I thought this would be really easy, changing the old code from this:

def update
  @request = Request.find_by_edit_id(params[:edit_id])
  if @request.update_attributes(request_params) 
    flash[:success] = true
    redirect_to edit_request_path(@request.edit_id)
  else
    render 'edit'
  end
end

And adding one additional component to the "if" like this:

def update
  @request = Request.find_by_edit_id(params[:edit_id])
  if @request.update_attributes(request_params) && @request.changed?
    flash[:success] = true
    redirect_to edit_request_path(@request.edit_id)
  else
    render 'edit'
  end
end

But this doesn’t work. Now what happens is that, on the edit page, if I don’t change any info and hit submit, nothing happens (which is great), but if I DO change info and hit submit, still nothing happens (which is bad). What am I doing wrong?

Note: I initially thought it was an order of operations error, so I made it a nested if, with first if @request.update_attributes, and second if @request.changed, but this didn't work either...

like image 569
james Avatar asked Jan 23 '14 01:01

james


1 Answers

The update_attributes method includes the 'save' call as part of its method and is returning true if the save is successful. I think you're looking for something like this using assign_attributes:

def update
  @request = Request.find_by_edit_id(params[:edit_id])
  @request.assign_attributes(request_params)

  if @request.changed?
    if @request.save
      flash[:success] = true
      redirect_to edit_request_path(@request.edit_id)
    else
      render 'edit'
    end
  else
    # Action if no change has been made
  end
end
like image 107
Helios de Guerra Avatar answered Sep 20 '22 03:09

Helios de Guerra