views:

70

answers:

1

All/Anyone,

Curious what the prevalent Rails idiom is for indicating the success/failure of a particular action to the end user?

For example, let's say you have a restful User resource and update is invoked on said User resource; once the update has completed and I've routed the user back to edit.html.erb - I'd like to indicate whether or not the action was successful (which one would say == the absence of errors).

That said, three approaches come quickly to mind:

  1. if @user.errors.blank? then show 'success'. This doesn't work on the inital display of edit.html.erb

  2. Update flash to indicate success/failure based on the results of @user.save/update_attributes. if flash[:status] == :success then show 'success'.

  3. set an instance variable in the update action - much like flash - @success == true. if @success then show 'success'

Am I missing something? Perhaps there's a method on AR that I'm just not seeing? If @user.updated?

Thanks! Cory Wilkerson

+1  A: 

I usually just use flash[:notice] for notification messages such as "Your account was updated successfully" and either flash[:error] or error_msg_for for error messages. I use error_msg_for errors caused by validation failure and flash[:error] for all other kinds of error messages. Unless absolutely necessary I take care not to set them both on the same action.

I also try to avoid returning a use to a form they just submitted if their action succeeded. I think it's sending contradictory signals to post a success message and send the user back to the form they just submitted. My rule of thumb is "redirect on success, render on failure." For example, I will redirect to @user if @user is saved on an update, but will render :edit if the save is unsuccessful.

Sample controller code.

before_filter :identify_user, :except => :index

def update
  @user = User.find(params[:id])
  if @user.update_attributes(params)
    flash[:notice] = "Your account was updated successfully"
    redirect_to @user
  else
    render :action => :edit
  end
end

def index
end

def identify_user
  begin 
  @user = User.find(params[:id])
  rescue
    flash[:error] = "You specified an unknown user"
    redirect users_path
  end
end

My notification partial called in my application layout.

<div id="notification_area">
  <% flash.each do |key, value| %>
    <% if value %>
      <div id="<%=key%>">
        <%= value %>
      </div>
    <%end%>
  <%end%>
</div>
EmFi
This is consistant with all of Rails' scaffolding, too.
Steve Klabnik
Probably where I picked up the practice.
EmFi