Skip to content

Instantly share code, notes, and snippets.

@justinthiele
Created September 11, 2011 04:43
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save justinthiele/1209182 to your computer and use it in GitHub Desktop.
Retaining form data through a login process and resubmitting the form [Rails & Devise]

This is a feature I struggled with for quite awhile, so I thought I'd share my solution. The code is actually pretty simple once I got it figured out. Hopefully it will save somebody else some headaches.

So here's what we're doing

To create an easy on-boarding process, I've put a New List form on the front page of Favsi.com. However, creating a list requires the user to be authenticated, so I needed to create a way to retain the user's New List form data through the authentication/registration process, and then post it. Here's a screenshot of the front page: Favsi Front Page Form

The flow would go like this

  1. User goes to the front page.
  2. User fills out the New List form and presses the Create List button.
  3. If the user is not logged in, they are prompted to login or register.
  4. User logs in/registers using standard authentication or using the Facebook/Twitter Connect flow.
  5. Once logged in/registered, the form data from Step 2 gets submitted and the user is redirected to view their published list.

After much Googling, StackOverflowing, and asking Portland Ruby folks there seemed to be 2 possible approaches:

  1. Once the form is submitted, carry the form data through the login process in hidden fields then submit it once logged in.
  2. Write the form data to the user's session then retrieve and submit it once logged in.

Since Favsi offers Facebook and Twitter authentication (which routes the users off of Favsi.com) option 2 was the only choice.

The Code

The necessary code is in the lists_controller.rb and application_controller.rb files. Liberally commented :)

class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
# Check to see if there is a temporary list saved in the session
if session[:list].present?
# Save the list
@list = current_user.lists.create(session[:list]["list"])
# Clear the temporary list in the session
session[:list] = nil
# Redirect to the list
flash[:notice] = "Sweet, logged in. Nice list, btw :)"
user_list_path(@list.user, @list)
else
# If there is not a temp list in the session proceed as normal
super
end
end
end
class ListsController < ApplicationController
# Make sure not to filter 'create' as we'll be handling that with our redirect
before_filter :authenticate_user!, :except => [:show, :index, :create]
...
def create
# Check to see if the user is registered/logged in
if current_user.nil?
# Store the form data in the session so we can retrieve it after login
session[:list] = params
# Redirect the user to register/login
redirect_to new_user_registration_path
else
# If the user is already logged in, proceed as normal
@list = current_user.lists.new(params[:list])
respond_to do |format|
if @list.save
format.html { redirect_to(user_list_path(@list.user, @list), :notice => 'Sweet, your list has been created.') }
format.xml { render :xml => @list, :status => :created, :location => @list }
else
format.html { render :action => "new" }
format.xml { render :xml => @list.errors, :status => :unprocessable_entity }
end
end
end
end
@rubyonrails3
Copy link

If you have many actions which need to resubmit this won't work or it would be hard to maintain your code/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment