Posted September 22, 2012 by Spyros in Ruby on Rails

Handle Flash Messages And Redirects In Your Controllers


Rails is all about following the best practices. If you are just starting out, the path is pretty long. I’ve been studying Rails for many months and, to tell you the truth, i learn many new things every day. Rails is not like any other language or framework that you have used or are using now. It’s nature is changing all the time. As the creator of Rails has said (David Hannson) that if something new but great comes up, Rails will adapt to it at the very same time. Although i pretty much like that notion, it can be difficult to be up-to date with all the new things. In virtually every Rails project that you make, you will be refactoring your code all the time. It’s pretty natural. In this post, i want to show you how a controller should handle flash messages and redirects.

What are Flash messages and Redirects ?

Quite simply, they are what your application users see. They are the messages that users see and the pages they are directed to. It’s the flow of your program. This one should always be presented by controllers. Typically, a controller provides views with instance variables, like @user, sets flash messages and redirects users to specific pages. If you ever feel that you need to set flash messages inside models, you are thinking the wrong way and you have to refactor. The most typical flash messages are notice and alert. They are handled like flash[:notice] = ‘your_message_to_user’.

An Example Controller Method With A Flash And Redirect

What i like to do with my flashes and redirects is to set my flash key and redirect at the same time. Let me show you an example of a small action in one of my projects, where i am handling the sending of a private message :

  def create
  	@message = Message.new(params[:message])

  	flash[:error] = 'Cannot message yourself.' and redirect_to new_message_path and return if @message.check_if_sender_is_recipient
  	flash[:error] = 'This user does not exist.' and redirect_to new_message_path and return if not User.exists?(:id => @message.recipient_id)

  	if @message.send_message
  		flash[:success] = 'Message sent successfully' and redirect_to messages_inbox_url
  		render new_message_path

Now notice that i don’t care about xml, json or other responses in this example. You can very easily refactor to include other responses if you like. In this one, i get a new @message instance from an html form after it was being submitted. After i retrieve it, i make two simple checks. The first one is checking whether the supposed sender of the message is its recipient as well. If so, it displays an error, redirects to new_message_path(the new message form) AND returns.
It is VERY important that you do not forget to return as well. Otherwise, the redirection will occur, but the code right below it will still be executed and will actually send the message. I also check if the supposed recipient of the message actually exists. There are actually more checks that were happening in my actual project, but i think that a couple illustrate the point. If you get no errors, you can proceed with sending your message.