cancan how can we create roles dropdown in ROR - ruby-on-rails

I am using cancan for role management in my app. I have different roles in my app like Super Admin, Admin, developer, tester. How can I display roles dropdown from Roles array without including Super Admin and Admin. Please look at my code
class User < ActiveRecord::Base
Roles = [:super_admin, :admin, :developer, :tester]
end
I need a select box containing developer and tester, and tried to create a array using following code but null item is getting in dropdown.
User::Roles.map{|r|
next if %w(super_admin admin).include?(r.to_s)
r.to_s.humanize
}
Please help

A quick one-liner:
(User::Roles - [:super_admin, :admin]).map { |r| r.to_s.humanize }

roles = User::Roles.dup
roles.delete :super_admin
roles.delete :admin
The roles array will have all roles except super_admin and admin
[EDIT]
Actually I think this way is better
ADMIN_ROLES = [:admin, :super_admin]
roles = User::Roles.select {|r| !ADMIN_ROLES.include? r}

Related

Who handle the roles of a User in Rails?

I'm making a Rails 6 application where I'm using Devise for authentication, Pundit for authorization and I added Active-Admin because I need a dashboard where admin users manage the content of the app.
Other than admin, I have a couple of more roles president, manager, guest. An admin can be president or manager.
I'm little confuse on what to use to implement the roles, with devise? pundit? I do it by hand?
Is it better to unite the User and the AdminUser model active-admin created? Because this way UserAdmin users can't log in to the application, only to the dashboard and that is not what I want.
I have seen tutorials where people add an admin:boolean column to the users, should I do something like that?
Is it better to unite the User and the AdminUser model active-admin created? Because this way UserAdmin users can't log in to the application, only to the dashboard and that is not what I want.
That depends more on your business logic. It may be a good idea to keep your users and admin_users tables separated; The users table will probably need to have a lot of associations with other tables, that will not be necessarily needed by admin_users, right?
I'm little confuse on what to use to implement the roles, with devise? pundit? I do it by hand?
You may define a role column in your admin_users table, and use that column in pundit policies, for example:
class ResourcePolicy
# ...
# ...
# ...
def update?
user.admin? || user.president?
end
end
in AdminUser, you can do the following:
class AdminUser < ActiveRecord::Base
def admin?
role == 'admin'
end
def president?
role == 'president'
end
end
There are many other ways to implement that, and they all depend on what you need to achieve.

Using CanCan to assign permissions to roles

I have a rails application where I have set up a table: users another table: roles and finally a join table: user_roles where a user may have many roles, but a role belong_to_and_has_many :users
This has allowed me to create new roles and then, assuming thee user is an admin, on the user edit page, switch their role.
This is great, how ever currently no role has capabilities. What I was thinking was doing:
role_permissions table
permissions: has_and_belongs_to_many :roles
Setting up a set of checkboxes on the roles edit page to assign a set of capabilities
to said role, that can then be applied to said user, that can then be used by capybara to determine if a user has the appropriate action or not.
While you can create roles, you cannot create capabillities. so you would have a predetermined list of capabilities. Also some roles, such as administrator or member could not be destroyed or edited. (already done.)
I can set up the table and the relationship to do this, what I cannot figure out how to do is to integrate this concept with cancan. Because can can does something like:
can? :destroy #project
If I assign, say:
Role: Editor (String name)
Capabilities: Read, Write, Destroy, Update, Preview (These are just string names)
How could I then say:
can? user.role? Editor read Post - seudo code.
First of all, for capabilities, if it's a fixed list of capabilities you're working with, you're probably better off with having a number of booleans on the roles table, e.g. can_create_projects, can_create_users, etc., which encode the abilities of each role.
Then your CanCan Ability class might have something like the following,
class Ability
include CanCan::Ability
def initialize(user)
can(:create, Project) do |project|
user.roles.any?(&:can_create_projects)
end
end
end

How do i make a user an admin

I am creating a website in Ruby and I would like to have the option to sign up as an admin or a user. I have created the sign up system using devise and I would like to be able to give different permissions to different users, i.e Admins and Users. Thanks guys.
There's a comprehensive guide here.
Here's a post about using Devise and CanCan to accomplish what you are looking for.
You can add boolean fields admin and users into your User model. So while creating you can assign admin or user role.
This question is answered here:
how to define user roles
you can use devise + cancan and define roles like user and admin to separate common user and application admin.
class User < AB
has_many :roles
def is_admin?
roles.include?(:admin)
end
end
class Role < AB
end
and then check it in cancan's definition file like this
can :update, Model do |model|
user.admin?
end
this video give you detail about it http://railscasts.com/episodes/192-authorization-with-cancan

Devise/CanCan - Restricted Content

Building a rails B2B application that will have various users. I'm pretty clear on restricting access for internal staff using Devise and CanCan but I want to be able to give suppliers and customers their own login as well. Customer will be fairly simple, however, I want to ensure the supplier (label) login enables them to view and amend their own product and sales data only.
The model is roughly:
User (as setup by Devise)
Label [has_many releases]
Release [belongs_to label / has_many products]
Product [belongs_release / has_many tracks]
Track [belongs_product]
I'm guessing I could add in a label_id field on the user model and associate that way but I need internal users (and customers) to have access to view all label data. I also need to allow a label to have many users.
Would it simply be a case of defining a 'label' role via Cancan that enforces the use of a label_id in the the views? If that's the correct approach how do I then lock down the content to that label_id in my controllers/views? Role based if statements?
Thanks in advance!
What you'd first have to do is define some CanCan roles, like supplier, customer and staff, and then create an interstitial controller to handle the forking:
class CheckingController < ApplicationController
def index
#path = case user.role
when 'supplier'
supplier_path
when 'customer'
customer_path
when 'staff'
staff_path
else
admin_sign_in_path #or whatever
end
redirect_to #path
end
end
Then in your routes.rb file you can send users to either the root or index action of your controller by first sending them to CheckingController#index which will redirect based on your CanCan roles.

multiple roles in rails

I want to design a role based system like Basecamp. A user can be editor of a brand and also he can be a worker in another brand. I'm using devise + cancan. How can i design a database for this situation? Thanks.
I would recommend a role model. In this scenario a user would have_and_belong_to_many :roles while a role would have_and_belong_to_many :users. This creates a many to many relationship between roles and users. See this RailsGuide for more info on associations.
In your CanCan ability.rb file you can do something like this (I am just guessing at your setup):
can :manage, Brand do |brand|
user.has_role?("brand_manager") && user.brands.include?(brand)
end
In your user.rb file it's helpful to write something like this:
def has_role?(name)
role = Role.find_by_name(name)
(self.roles.include?(role)) ? (return true) : (return false)
end
Hope this helps.
acl_system2. Its an old plugin, but checkout its readme file to see if it serves the purpose.

Resources