Skip to content

How To: Create a guest user

richardkmichael edited this page Dec 21, 2011 · 18 revisions

In some applications, it's useful to have a guest User object to pass around even before the (human) user has registered or logged in. Normally, you want this guest user to persist as long as the browser session persists.

Our approach is to create a guest user object in the database and store its id in session[:guest_user_id]. When (and if) the user registers or logs in, we delete the guest user and clear the session variable. A helper function, current_or_guest_user, returns guest_user if the user is not logged in and current_user if the user is logged in.

    class ApplicationController < ActionController::Base
    
      protect_from_forgery
      
      # if user is logged in, return current_user, else return guest_user
      def current_or_guest_user
        if current_user
          if session[:guest_user_id]
            logging_in
            guest_user.destroy
            session[:guest_user_id] = nil
          end
          current_user
        else
          guest_user
        end
      end
      
      # find guest_user object associated with the current session,
      # creating one as needed
      def guest_user
        User.find(session[:guest_user_id].nil? ? session[:guest_user_id] = create_guest_user.id : session[:guest_user_id])
      end
    
      # called (once) when the user logs in, insert any code your application needs
      # to hand off from guest_user to current_user.
      def logging_in
      end
    
      private
      def create_guest_user
        u = User.create(:name => "guest", :email => "guest_#{Time.now.to_i}#{rand(99)}@email_address.com")
        u.save(false)
        u
      end
    
    end

Finally in order to fix the problem with ajax requests you have to turn off protect_from_forgery for the controller action with the ajax request:

    skip_before_filter :verify_authenticity_token, :only => [:name_of_your_action] 

Another option is to remove protect_from_forgery from application_controller.rb and put in each of your controllers and use :except on the ajax ones:

    protect_from_forgery :except => :receive_guess
Clone this wiki locally