8

currently I have a rails 3 app with devise. it requires the users to register / signin for access.

I would like to enable guest users. So that when a user visits certain views a guest user account is created for that user and then if/when they authenticate/register that guest user is then upgraded to a normal user.

Think of the app as a chat room. I want guest users to be able to join the chat room, then later oauth into twitter to register. But I don't want to force users to register before joining.

Suggestions?

I found this: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user

Problem with that is I added the helper, but don't understand how to initiate current_or_guest_user. Also not sure how to initiate per specific allowed views?

Any ideas? Pointers? Thanks

Leszek Andrukanis
  • 2,114
  • 2
  • 19
  • 30
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012
  • If i add the methods in the link to my ApplicationHelper and then call the following in the controller 'user = current_or_guest_user' when does it error with: undefined local variable or method `current_or_guest_user' for – AnApprentice Jun 17 '11 at 21:26
  • Also tried adding 'include ActionView::Helpers::ApplicationHelper' in the controller but now I get: uninitialized constant ActionView::Helpers::ApplicationHelper – AnApprentice Jun 17 '11 at 21:29
  • 1
    Don't worry about including your helpers, they get automagically included as long as you put them in the right place. Are you getting a specific error message? Can you put it in a pastebin? – colinross Jun 17 '11 at 21:44
  • The error is in the first comment. Rails isn't finding current_or_guest_user – AnApprentice Jun 17 '11 at 21:48
  • Here is a pastebin http://pastebin.com/0Lj25mwa – AnApprentice Jun 17 '11 at 21:50
  • If I put the methods in the wiki in the application controller it seems to work. so why does the wiki say a helper? – AnApprentice Jun 17 '11 at 22:05
  • Also, User.create won't save unless the user object has an email and password. interesting how there is no mention of that anywhere. – AnApprentice Jun 17 '11 at 22:07
  • email and password are required fields by the model you associate with devise-- its mentioned in the docs. The wiki suggests using a helper so the function is automagically available in the views as well-- in general, its best practice to use helper modules for this kind of functionality. Its very weird that your ApplicationHelper isn't being loaded into automatically – colinross Jun 17 '11 at 22:27
  • colinross - that makes sense but why would they then have a wiki page with a solution that doesn't work? – AnApprentice Jun 17 '11 at 22:29

3 Answers3

14

Another more transparent way is this:

def current_user
  super || guest_user
end

private

def guest_user
 User.find(session[:guest_user_id].nil? ? session[:guest_user_id] = create_guest_user.id : session[:guest_user_id])
end

def create_guest_user
  u = User.create(:name => "guest", :email => "guest_#{Time.now.to_i}#{rand(99)}@example.com")
  u.save(:validate => false)
  u
end
Kris
  • 19,188
  • 9
  • 91
  • 111
  • Really nice approach. I am now doing the same thing, but I chose to add an "is_guest" to my user model so I can every once in a while go through the DB and delte guest users. – Automatico Oct 26 '12 at 22:06
  • Good suggestion about adding an `is_guest` boolean so you can sweep out old guest users periodically. – Kris Jun 18 '13 at 10:03
3

After following the wiki, just replace calls to current_user with current_or_guest_user

As far as views goes, do it in the controller with a before_filter.

Without seeing any code from you it is hard to guess, but in pseudo-code it would be something like

class ChatController < ApplicationController
 before_filter authenticate_user!, :except => [:join]  #this will force users to log in except for the join action

  def join
   chat_handle = current_or_guest_user.handle
   # some more code...
  end 
colinross
  • 2,075
  • 13
  • 10
2

Checkout this rails cast about guests users. Details about Devise at around 5:40.

Benjamin Crouzier
  • 40,265
  • 44
  • 171
  • 236