Thursday, April 21, 2011

Rails Idiom for Post-Update Notification

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

From stackoverflow
  • 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>
    
    Steve Klabnik : This is consistant with all of Rails' scaffolding, too.
    EmFi : Probably where I picked up the practice.

0 comments:

Post a Comment