Does Devise supports deferent models for deferent roles? (in rails) - ruby-on-rails

I use Devise in my new project,but I have some problems in roles.
There are two kinds of user in my project,but these two kinds of user have deferent data structure(very different).
I Know Devise supports roles,but how should I deal with the deferent user data structure?
Thank you.

Devise documentation states that you can have as many Roles with different models as you want (configuring multiple models)
You just set up the other model as you did with the first one and then add to routes.rb
devise_for :admins
And then you can use inside your controllers and views:
# Inside your protected controller
before_filter :authenticate_admin!
# Inside your controllers and views
admin_signed_in?
current_admin
admin_session
The main question is how to let both of these accounts access the same controller (if it is applicable to your case), because of the two before_filters the first would always redirect to login page, if that is not the logged-in role (say :admin). You would probably have to implement a custom before_filter to validate the session against two roles simultaneously.
You could probably work around this with custom routes for these roles. E.g /admin/projects and /user/projects. In that case the authenticate method could be helpful.

Related

When using cancancan with devise, does devise need to be added to ability.rb?

Question: when using cancancan for authorization and devise for authentication, do I have to define any authorizations for the devise part of the app, or does devise take care of everything itself?
Example
For example, for (all) other resources, we should place load_and_authorize_resource in the controller of that resource so that users who should not access it are prevented from doing so. Then, to allow access to those should have access, we can define abilities by adding code like this to ability.rb:
# ability.rb
can [:index, :show], [Patient], user_id: user.id
Back to my question - do I have to add load_and_authorize_resource to any of devise's controllers and define permissions for devise controllers in ability.rb? OR does devise take care of all that without the developer having to do anything?
We obviously don't want to allow one user to change another user's account info!
It's important to distinguish between devise authorization part of account info (session creation/logout/email+password+restoration/changing if you have that enabled) and any other custom logic and data related to it (for example - names, shoe sizes, whatever) that is kept inside or accesses the same model.
Devise controllers, if you did not change them much - are very simple and do not need additional access control because by design user is only able to edit their own auth data (they simply do not handle user id from outside thus there's no way to tamper it). Moreover just adding load_and_authorize_resource will at least have no effect or more probably will interfere with existing devise code because it was not designed around cancancan.
But if you have your own controllers for user profile(s), like user index, admin editing other's profiles etc - obviously, you have to facilitate access control there.

CRUD actions on a Devise User model - Rails 5

I'm working on a project that has a User Devise model and an Admin Devise model, and I want an Admin to be able to perform CRUD on the User model.
I've set up both Devise models following the Devise Wiki's How to Setup Multiple Devise User Models guide (including step 4 - exposing the scoped controllers).
This has given me the Devise views and controllers for confirmations, passwords, registrations, sessions and unlocks, but no users_controller to add CRUD actions to.
Could I simply create a users_controller and make sure it uses the correct users table in the database, or should I add CRUD actions to the registrations_controller?
Is the above advisable, or is there a more elegant way of setting up a CRUD interface for an Admin to be able to manage the User model?
Any help would be much appreciated.
Devise works only with sign_up/sign_in process. It assumes not only simple user creation, but some more things, like email sending.
So if you want to create/update/destroy users you need to create separate UsersController. It is better to add an admin namespace to it

Devise model without devise routes

I have two Rails projects sharing some files, one is the actual app and the other one is the admin tool for the app. They share migrations, models, some config, etc. The admin tools is ActiveAdmin 1.0.0-pre2 and Rails' version is 4.2.
I have two Devise models, User and AdminUser. In the app project, there's no route for admin_user and I want to keep it that way, but if I don't add:
devise_for :admin_users
to the routes file, I get all sort of strange errors, such as:
ActionView::Template::Error: undefined method `admin_user_confirmation_url' for #<ActionDispatch::Routing::RoutesProxy:0x007fc613ecde08>
or:
Could not find a valid mapping for <AdminUser ...>
whenever I'm creating an AdminUser in the app project (sample data generation).
How can I achieve having a devise model, without the routes?
If you just want a model for Admin, to Have some methods and data, remove all devise entries (database_authenticatable, etc.) from the admin user migration and model, and use it as a plain activerecord model. If you need any specific devise modules, you can add them one by one. But the devise modules you add will likely require the controller and routes to be present.
What I would do if I were you:
Merge the two applications into one.
Create a new field in the User migration and call it "role", with default value "user"
Use Cancan or something similar to set different permissions depending on the role ("user" or "admin"). For example users with role "user" cannot view any of the admin pages. And this way whoever is admin in your website, doesn't need to have a separate model/account for loging in to active admin.
Don't get me wrong, I just can't think of a good reason to keep the two sides as different projects. It will only add problems to your logic and implementation and you will have to constantly be passing information around. I actually use ActiveAdmin in the way I explained above and everything works like a charm.

Rails polymorphic association - controllers and views?

I have a model User (used for authentication purposes) which is connected to two other models, Customer and Seller via polymorphic association in Rails. A customer and seller must have different sign up forms because of their different data but can use a single login form because they're both Users. In order to manage the customer and seller resources separately, is it a good idea to create respective controllers and views for them, or should management of all Users be done in the UsersController?
It depends upon the design of the two views customers and sellers. If the design of both the views are different then I will encourage you to create two controllers customers_controller and sellers_controller and you may want to have a module for common actions like lib/authentication.rb.So
# customers_controller.rb
include Authentication
def some_action
end
and
# sellers_controller.rb
include Authentication
def other_action
end
Authentication file like
# lib/authentication.rb
module Authentication
def common_method
end
end
You can have two controllers and one module which you can write common methods/actions
As #madyrockss pointed out, STI is probably the way to go here because User.find(params[:login]) will return either an instance of Customer or Seller automatically.
I would encourage forgetting about the UsersController and views and encourage thinking in terms of seller and customer controllers/views (that is, don't share a single controller and views per action that can handle either customer or seller and has conditionals within view determining what to show). If the two users have different business rules, the whole thing starts to get messy real quick and becomes unwieldy to manage as business rules change.
For login/logout, if the form is going to be the same for both, then a single controller will suffice and I'd consider a different name than UsersController, such as SessionsController to be more semantically in line with what the controller's purpose is. You are not confined to a one-to-one Models <==> Controllers <==> Views which many beginning Rails developers fall into the trap of.

Creating new users through Devise with an admin user who is already logged in

I'm building a service on Rails using Devise which requires an 'admin' user to add regular users to their organization account.
The default behaviour of Devise doesn't support this, as the ':require_no_authentication' method is called when a logged in admin user tries to create a regular user account.
What would be the recommended method of achieving the functionality I am looking for?
:require_no_authentication is called by prepend_before_filter in the
Devise::RegistrationsController class, rather that in one of the
RegistrationsController methods, so I do not know if this can be
overridden (correct me if I'm wrong).
I believe separating the admin users from the regular users would
work, however these users will share very similar properties, so I
believe doing this will add unnecessary repetition.
I am currently trying to create new admin users (who in turn create
the organization that regular users belong to) using the regular
Devise sign up flow with 'users#new' and 'users#create' controller
actions, and allowing admins to add new users through a 'users#add'
action.
If there is perhaps another good user authentication gem that would better suit my needs, I would be happy to take a look at switching to that.
This seems to be more of an authorization problem than an authentication problem. You can use an authorization gem, such as cancan, to assign roles to users (such as admin) and grant abilities to those roles. This works really well alongside Devise. Here's a tutorial:
http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/
EDIT: I think I may have misunderstood your problem. Maybe what you need is just another controller to handle the creating of users outside of the Devise controllers. You could use cancan to restrict access to this controller to only admins.

Resources