Search code examples
ruby-on-rails-4deviserolifypunditreform

Rolify and Rails 4 role management


I am trying to implement a role based access system in my rails 4 app, and I want the end user (super_admin) to have the ability to edit role assignments via the UI.

I have achieved some success but can't help feeling that there has to be a better way (Since I'm new to rails). Here is my code:

users_roles_controller.rb

# GET /user_roles/new/:id
def new
  @roles = Role.all
end 

# POST /user_roles/new/:id
def create
  populated = params[:roles][:name].reject(&:empty?)
  populated.each do |key|
    @user.add_role  Role.find(key).name
  end 

  redirect_to users_path
end 

And in my Form (HAML and simple_form):

= simple_form_for :roles, :url => create_user_roles_path(@user.id), :method => "post" do |f|

= f.input :name, :collection => @roles,   as: :check_boxes

= f.button :submit

I'm struggling with the following:

  1. How do I validate form entries, since there is no model?
  2. Should I be using strong parameters and if so how do I implement on a form without a model
  3. How do I create something similar, but with Current roles already checked? (True role management)

UPDATE I have looked at using the reform Gem as suggested by the comments. This seems like a great solution. I am however having issues with the implementation on this case.

Let me map it out: I have 3 tables in the database:

  1. users
  2. users_roles (Mapping Table with 2 Attributes : user_id & role_id {Join Table -> HABTM})
  3. roles

I want to construct a form with all the values in the Roles model as checkboxes.The checkboxes should dictate what values are fed into the users_roles table (With relation to a specific user). What I want reform to do is validate the input of this form. This form will always display all of the values in Roles, but some/all of the boxes might be unchecked.

I have created a form folder in my app and started with the following code:

class UserRoleForm < Reform::Form

property :user__id, on: :user
property :role_id, on: :role

validates :user__id, presence: true
validates :role__id, presence: true
end

Am I going in the right direction?

Thanks for the help.


Solution

  • You need two things to build your form: a user's roles and the possible roles.

    If I recall correctly, rolify gives your model associations ad should just let you do something like some_user.roles to return all the roles applied to some_user.

    To get possible roles, try Role.all.

    To combine both, try

    user_roles = some_user.roles.pluck(:name) # suppose this returns ["admin"]
    Role.pluck(:name).map { |r| [r, user_roles.include?(r)] }
    

    You now have an array like this that you can use to build your form checkboxes with an each loop.

     [["customer", false], ["admin", true], ["editor", false]]
    

    Define your reform object's sync or save method to handle what to do with the submitted input, however you are handling it. You can (SHOULD) make a custom validation to verify if the submitted roles are valid roles.