Devise: Manually sign_in(@user) doesn't set the session

Created on 16 Oct 2010  路  9Comments  路  Source: heartcombo/devise

Hi, I'm using devise with Mongoid with Account and User document relation with subdomain.
So far its going well, but the sign_in(@user) doesn't set the current_user.

I'm using this in acounts_controller.rb coz I just want the user to be logged in automatically as soon as he creates an account, though the information are stored successfully in the db.

And even when I go to http://subdom.localhost:3000/users/sign_in and I enter the valid credentials, I never get logged in.

# accounts_controller.rb
def create
  @account = Account.new(params[:account])
  @user = @account.users.first
  respond_to do |format|
    if @account.save
      sign_in(:user, @user)
      debugger
      format.html { redirect_to(root_url(:host => with_subdomain(@account.subdomain)), :notice => 'Account was successfully created.') }
      format.xml  { render :xml => @account, :status => :created, :location => @account }
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @account.errors, :status => :unprocessable_entity }
    end
  end
end

# account.rb
class Account
  include Mongoid::Document
  accepts_nested_attributes_for :users
  field :subdomain, :type => String
  references_many :users
  validates :subdomain, :presence => true
end

# user.rb
class User
  include Mongoid::Document
  include Mongoid::Timestamps
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable, :lockable and :timeoutable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, 
         :validatable, :authentication_keys => [ :email, :subdomain ]

  #embedded_in :account, :inverse_of => :users
  referenced_in :account

  field :email
  field :username

  validates :username, :presence => true

  def self.find_for_database_authentication(conditions={})
    if account = Account.where(:subdomain => conditions.delete(:subdomain)).first
      account.users.detect { |u| u.email == conditions[:email] }
    else
      nil
    end
  end
end

Most helpful comment

To login in a user automaticly you can use warden as well.

warden.set_user @user

All 9 comments

To login in a user automaticly you can use warden as well.

warden.set_user @user

Thanx maxschulze, but that didn't work for me.
I am wondering that the overridden method self.find_for_database_authentication() method is not doing what its supposed to do?

Hum, I think in the self.find_for_database_authentication() you have to only set the conditions, and then call super like this:

def self.find_for_authentication(conditions = {})
  conditions = [
    "user_name LIKE ? or email LIKE ? or (first_name LIKE ? and last_name LIKE ?)",
    conditions[:email],
    conditions[:email],
    conditions[:email],
    conditions[:email]
  ]
  super
end

Actually, did you notice above or not that I'm using this with Mongoid. So, I came across this wiki http://github.com/plataformatec/devise/wiki/How-To:-Embed-users-in-your-account-model-with-Mongoid and a gist link in that wiki http://gist.github.com/446144 The gist itself is not pretty clear enough.
So, I think that the code you suggested doesn't fit, I might be wrong!!

Well, I checked using debugger, step by step, the account and user both are created, stored in session and the current_user is also set before redirecting to the dashboard controller. As soon as its rendered, the current_user is nil.

I am not sure whether my routes is the devil.
# config/routes.rb
Cloudfactory::Application.routes.draw do
resources :accounts
constraints(Subdomain) do
devise_for :users
root :to => 'dashboard#show'
end
root :to => "home#index"
end

# app/helpers/url_helper.rb
module UrlHelper 
  def with_subdomain(subdomain)  
    subdomain = (subdomain || "")  
    subdomain += "." unless subdomain.empty?  
    [subdomain, request.domain, request.port_string].join  
  end

  def url_for(options = nil)  
    if options.kind_of?(Hash) && options.has_key?(:subdomain)  
      options[:host] = with_subdomain(options.delete(:subdomain))  
    end  
    super  
  end
end

# includes the above UrlHelper Module
class ApplicationController < ActionController::Base
 include UrlHelper
 ...
end

And the overridden method def self.find_for_authentication() in the User model is never called.
class User
include Mongoid::Document
include Mongoid::Timestamps

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, 
         :validatable, :authentication_keys => [ :email, :subdomain ]

  referenced_in :account
  def self.find_for_authentication()
    puts "From overridden method"
    ...
  end
end

Its pissing me off!!

I have exactly the same problem...

I am having a similar problem but in devise 1.0.8 .. when trying to sign in right after a user is created , using sign_in(@user), doesn't set the warder key properly .

If you are still having this issue make sure your User model is validated and saved

I'm facing the same issue and my User model is validated and saved. I'm using ActiveRecord 3.2, Devise 2.0.4 and inherited_resources 1.3.1. This is the code of my action :

def update
  update! do |success, failure|
    success.js  { sign_in @user, :bypass => true }
  end
end
Was this page helpful?
0 / 5 - 0 ratings