Questifer
Questifer

Reputation: 1133

Multiple devise user type root routes

I have just set up my STI structure with a Devise User model. I have two user types (business and lender) and would like them to be sent to separate root paths after signing in. My models look like this:

user.rb
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :type
end

lender.rb
Class Lender < User
end

business.rb
Class Business < User
end 

My routes file looks like:

Lendingloop::Application.routes.draw do
  # User route
  devise_for :users, skip: [:registrations]

  # Lending routes
  devise_for :lenders, skip: :sessions
  authenticated :lender do
    root :to => "LenderAccount#dashboard", :as => "lender_authenticated_root"
  end 

  #Business routes
  devise_for :businesses, skip: :sessions
  authenticated :business do
    root :to => "BusinessAccount#dashboard", :as => "business_authenticated_root"
  end 

  # Error Routes
  get "/404", to: 'errors#not_found'
  get "/422", to: 'errors#unacceptable'
  get "/500", to: 'errors#internal_error'

  # Root route
  root :to => 'StaticPages#landing'
end

As you can see I have an authenticated do block which I would like to redirect lenders and businesses to their specific root pages. I have a LenderAccount and BusinessAccount controller setup with dashboard actions in them and corresponding views.

When I log in as a lender or a business, I'm redirected to my root_path which is 'StaticPages#landing'. That should only be for non-logged in users.

Update

I went through the devise documentation and added the following to my application_controller.rb file:

  def after_sign_in_path_for(user)
    if user.type == "Business"
      business_authenticated_root_path
    elsif user.type == "Lender"
      lender_authenticated_root_path
    else 
      root_path
    end 
  end 

I am also seeing a strange error in my console when I attempt to go to the dashboard page directly from lender_authenticated_root_path:

Rendered /Users/questifer/.rvm/gems/ruby-1.9.2-p320@rails3tutorial/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.7ms)
[2014-04-22 12:31:31] ERROR Errno::ECONNRESET: Connection reset by peer
    /Users/bvlaar/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/webrick/httpserver.rb:56:in `eof?'
    /Users/bvlaar/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/webrick/httpserver.rb:56:in `run'
    /Users/bvlaar/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'

Does anyone have an idea as to how I can get these authenticated blocks to handle the proper root redirects?

Upvotes: 1

Views: 1751

Answers (2)

Questifer
Questifer

Reputation: 1133

I got the roots working by changing my routes.rb file to:

routes.rb

root :to => 'business_account#dashboard', :constraints => lambda { |request| request.env['warden'].user.class.name == 'Business' }, :as => "business_root"
root :to => 'lender_account#dashboard', :constraints => lambda { |request| request.env['warden'].user.class.name == 'Lender' }, :as => "lender_root"

Now my two user types can login to their accounts and be directed to their respective controllers and dashboards.

Upvotes: 4

Shazam
Shazam

Reputation: 301

I think I can help. I had a similar problem. In my routes.rb file I created a "home" screen for non-logged in users.

Rails.application.routes.draw do

  root "home#index"

  devise_for :users 

  resources :home
  resources :dashboard

The home_controller.rb looks like this:

class HomeController < ApplicationController

def index
  if user_signed_in?
    redirect_to :controller=>'dashboard', :action =>'index'
  end
end

end

dashboard_controller.rb looks like this, and is only for logged in users:

class DashboardController < ApplicationController
before_filter :authenticate_user!

def index    
end


end

The views for each (home.html.erb & dashboard.html.erb) can then reflect content for visitors or logged in users.

I used this tutorial to sort it out. I don't know if it's overkill or not, this is my first application, but ti seems to be what you are asking for.

http://www.tonylea.com/2012/rails-authentication-with-devise/

Hope that helps.

Upvotes: 0

Related Questions