rails devise check class of logged in model - ruby-on-rails

I have multiple models which are using devise like Admin, Student and Counselor
I don't want to use roles as it 'll complicate things in this case.
I want to use one layout and show menus etc. depending upon class of model like
= render "shared/#{resource.class}_menu"
Is there way that I can get class of logged in object without if else conditions like we do in after_sign_in_path_for etc.

So what I do in this case where you want to have different areas for Admin, Student and Counselor
you can namespace each role or log in like this
#config/routes.rb
Rails.application.routes.draw do
devise_for :admins, :controllers => { registrations: 'admins/registrations',
sessions: 'admins/sessions',
passwords: 'admins/passwords',
confirmations: 'admins/confirmations'
}
authenticate :admin do
namespace :admins do
....
root :to => 'something#index'
end
end
devise_for : students, :controllers => { registrations: 'students/registrations',
sessions: 'students/sessions',
passwords: 'students/passwords',
confirmations: 'students/confirmations'
}
authenticate :student do
namespace :students do
....
root :to => 'something#index'
end
end
Now you can create the devise model for each namespace.
#app/controllers/admin_controller.rb
class AdminController < ApplicationController
before_filter :authenticate_admin!
end
For Devise controllers you can use them like tihs
#app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
end
For basic application controllers, you can use them like this.
#app/controllers/users/somethings_controller.rb
class Users::SomethingsController < UserController
...
end
I hope that this is able to help you

Related

Authenticated Devise root with username

If a user is logged in with Devise, I'd like to redirect them to their Posts index.
/username/posts
According to the Devise docs
I can use an authenticated block.
authenticated :user do
....
end
But I need the user's username to redirect there. Something like this.
authenticated :user do |user|
get '/', to: user_posts(user)
end
But this is not supported.
How to redirect with the current user to an authenticated root?
Edit:
NOT trying to do a after sign in Devise path. Trying to achieve a permanent root for logged in users and one for logged out users.
Try that:
class ApplicationController < ActionController::Base
def after_sign_in_path_for(user)
user_posts_url(user)
end
end
So you can do something like this
in your routes:
#config/routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => {
...
}
authenticate :user do
namespace :users do
...
root :to => 'posts#index' # /users/posts # this will only be accessible to login users
end
end
root :to => 'pages#index' #/pages this is accessible to all people
end
you will need:
#app/controllers/user_controller.rb
class UserController < ApplicationController
before_action :authenticate_user!
end
and
#app/controllers/users/posts_controller.rb
class Users::PostsController < UserController
def index
#posts = current_user.posts
end
...
end
I hope that this helps

Devise current_user with single table inheritance

I have a user model with an admin submodel.
class Admin < User
end
I have devise set up and a 'type' column in the user model. The routes look like this:
devise_for :users, :controllers => { :sessions => 'sessions' }, :skip => :registrations
devise_for :admins, :skip => :sessions
I am unclear on how to override devise so I can access an admin using the current_user helper.
Right now name is undefined from <%= current_user.name %>
Is an admin not also a user? I'm not sure why current_user is nil.
In my sessions_controller I have:
class SessionsController < Devise::SessionsController
def create
rtn = super
sign_in(resource.type.underscore, resource.type.constantize.send(:find, resource.id)) unless resource.type.nil?
rtn
end
end

Sharing RegistrationController for two devise models

I have two devise models, Individual and Group. I'm trying to share similar behavior for Registrations/Confirmations (send users to a page that informs them that an email has been sent, or send them to the edit page after confirmation, etc.)
My issue is that this works for Individuals, only. It has yet to work for Groups.
config/outes.rb:
devise_for :individuals, :controllers => {:confirmations => "Confirmation", :registrations => "Registrations"}
devise_for :groups, :controllers => {:confirmations => "Confirmation", :registrations => "Registrations"}
app/controllers/registrations_controller.rb:
class RegistrationsController < Devise::RegistrationsController
def after_inactive_sign_up_path_for(item)
"/post_sign_up?email=#{item.email}"
end
end
app/controllers/confirmation_controller.rb:
class ConfirmationController < Devise::ConfirmationsController
def after_confirmation_path_for(name, resource)
case resource.class
when Individual then edit_individual_path resource
when Group then edit_group_path resource
else super name, resource
end
end
end
The above code works for individuals, only. Can't figure out why though.
I was focused so heavily on the provided lines in routes.rb, I failed to notice another "devise_for :groups" at the top of the file. Apparently devise will override previous values in this case. Stupid mistake.
for scale & no errors - better to devide.
admin_registration_controller.rb:
class AdminRegistrationsController < Devise::RegistrationsController
end
user_registration_controller.rb:
class UserRegistrationsController < Devise::RegistrationsController
end
routes:
devise_for :admins, controllers: { registrations: 'admin_registrations' }
devise_for :users, controllers: { registrations: 'user_registrations' }

Rails NameError (uninitialized constant Registration):

I am currently using Cancan and my users basically have different 'roles'.
I only want people to be able to register 'consumer' user accounts and for business accounts admins will be doing that.
So now, I have this in my ability.rb
def initialize(user)
user ||= User.new
...
# You can only create accounts that are consumers
can :create, User do |user|
user.role? :consumer
end
and in my controller/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
load_and_authorize_resource
end
and config/routes.rb:
devise_for :users, :controllers => {
:registrations => "users/registrations"
}
Now when I visit the registration page, I am seeing "uninitialized constant Registration" with NO stack trace whatsoever. Any ideas?
My code example
class ApplicationController < ActionController::Base
authorize_resource
check_authorization
end
class Users::SessionsController < Devise::SessionsController
skip_authorize_resource
skip_authorization_check
end
For load_and_authorize_resource you will need skip_load_and_authorize_resource. And all this code is applicable for custom devise's controller. Just create one.
The issue is with the routes, please follow the following steps
1. $ rake routes, you will see the list of routes
2. In your config/routes.rb write the route you need, In my case the route to create a new user was,
devise_for :users, :controllers => { :new_user_registration => "users/registrations#new" }
3. restart rails server

Devise custom registrations controller error

When I try to create a custom devise controller:
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
# add custom create logic here
end
def update
super
end
end
I get a following error:
Unknown action
AbstractController::ActionNotFound
It is not the problem with routes. I tried to inherit RegistrationsController from ApplicationController and it works fine. As soon as i try to inherit from Devise::RegistrationsController it shows an error. It can't be an action problem to, becuse I tried to create a different action, and I get the same error.
# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
root :to => "registrations#new"
Using Rails 3.0.4
In your routes you have to use devise_scope if you are overriding devise default actions.
devise_for :users, :controllers => {:registrations => "registrations"}
devise_scope :user do
root :to => "registrations#new"
end
For a similar issue please see http://groups.google.com/group/plataformatec-devise/browse_thread/thread/a5beaaf4b1ad343a
Also here are the docs on changing default sign in routes, I know this you are doing registration, but this could be similar: https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
I used the following code in my project successfully:
app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
end
routes.rb
devise_for :users, :controllers => { :registrations => "users/registrations" }

Resources