ruby-on-railsrolify

Rolify Gem: User has to have at least one role


How can I validate presence of at least one role for a User using rolify gem? I tried validating presence of roles in User.rb as per below, but it does not work.

Bonus: Is it possible not to permit admin user take off his own Admin role?

User.rb:

class User < ApplicationRecord
  rolify
  validates :roles, presence: true
end

Edit Form:

  = form_for @user do |f|
    - Role.all.each do |role|
      = check_box_tag "user[role_ids][]", role.id, @user.role_ids.include?(role.id)
      = role.name
    = f.submit

Controller:

class UsersController < ApplicationController
  before_action :set_user, only: [:edit, :update, :destroy]

  def edit
    authorize @user
  end

  def update
    authorize @user
    if @user.update(user_params)
      redirect_to users_path
    else
      render :edit
    end
  end

  private
  def set_user
    @user = User.find(params[:id])
  end

  def user_params
    params.require(:user).permit({role_ids: []})
  end
end

When the user has 1+ roles it works ok, but if I take away all the roles it gives an error:

enter image description here


Solution

  • You can create a custom validation to requires that the user has at least one role:

    class User < ActiveRecord::Base
      rolify
      validate :must_have_a_role
    
      private
      def must_have_a_role
        errors.add(:roles, "must have at least one") unless roles.any?
      end
    end 
    

    The presence validation is really only intended for attributes and not m2m associations.

    Is it possible not to permit admin user take off his own Admin role?

    Its possible but will be quite complex since Rolify uses a has_and_belongs_to_many assocation and not has_many through: which would let you use association callbacks.