57

I have a form where I collect a lot of information in Rails. Part of this form is fields for a new user to register. Since Devise has controllers/actions specifically to create a new user, I don't know how to programmatically create a user in an entirely different action that also creates another record. I really can't have the user registration form separate. I can't figure out how to create a user, and then log the user in, like I could easily do in Authlogic.

I have used both Authlogic and Devise, and think each has their strengths and weaknesses. With Devise, I love how quick it is to "get going" with a new project, but customizing it seems to be a pain. Authlogic had so many problems with Rails 3 a while back, that I switched to Devise. I'm now working on a new project and get to start from scratch.

So I think there are 2 potential answers to this question: (a) how to do this in Devise, or (b) why I should just switch to Authlogic with Rails 3 instead.

Sean Coleman
  • 1,287
  • 2
  • 10
  • 10

3 Answers3

95

You can create a new Devise user simply by creating a new user model (see https://github.com/plataformatec/devise/wiki/How-To:-Manage-users-through-a-CRUD-interface)

@user = User.new(:email => 'test@example.com', :password => 'password', :password_confirmation => 'password')
@user.save

To sign in your newly created user, use sign_in @user

David Sulc
  • 25,946
  • 3
  • 52
  • 54
  • The exact same code works for Authlogic too (I'm running version 1.4.4.1). – Kenny Evitt Mar 19 '11 at 05:37
  • where is the documentation for this.. as in how does one know that a function named sign_in exists – codeAnand Dec 16 '11 at 11:57
  • 3
    You can see it in the "test helpers" section in the readme at https://github.com/plataformatec/devise More specifically, you can see the documentation here: http://rubydoc.info/github/plataformatec/devise/master/frames – David Sulc Dec 16 '11 at 14:11
13

Saving the newly created user before sign_in will fail because devise has not yet filled the required fields for User object yet. So David's code will work for the current page, but the next page won't get the signed in user, since the user is only saved after the session is set. This happens when I use Mongoid, and I don't know if it is a problem specific to Mongodb.

To address this problem, I have a very imperfect solution to call sign_in twice. The first sign_in will save the user. It just works but people can improve it certainly.

@user = User.new(:email => 'test@example.com',
                 :password => 'password',
                 :password_confirmation => 'password')
# This will save the user in db with fields for devise
sign_in @user
# :bypass is set to ignore devise related callbacks and only save the
# user into session.
sign_in @user, :bypass => true 
vanship82
  • 289
  • 3
  • 3
  • 2
    May i ask if the problem still occurs if you explicitly save the user before calling sign_in ? And if that doesn't work, does adding a call to reload the user after saving but before sign_in ? – m3z Oct 14 '13 at 22:30
4

For new people seeing this question...

A simple way to do this is in your

config/routes.rb

you should have a line like the following :

devise_for :users

so, you just have to add a path prefix that devise will use:

devise_for :users, :path_prefix =>'auth'

Hope it helps!

Ajay Barot
  • 1,681
  • 1
  • 21
  • 37