Search code examples
ruby-on-railscallbackrolify

Is it possible to skip role removing using callbacks with rolify gem for Rails


I use rolify in my Rails app and I'm trying to stop the process "remove role" with callback but it does not seem to do what I want.

rails 6.0.3 / rolify 5.3.0

this is my code

class User < ApplicationRecord
  rolify before_remove: :check_remove_role
  # ...
  def check_remove_role(role)
    puts 'Remove role'
    # Do not remove role if User is the only super_admin
    return false if role.name=='super_admin' && User.with_role(role.name).count == 1
  end
end

When I call user.remove_role(role) the callback pass, but the "removing process" does not stop even if the callback return 'false'.

Is there something wrong in my code ? or do I have to do it another way (maybe I can not use callback for this) ?


Solution

  • It looks like you are hoping to use these callbacks like an ActiveRecord validation. They are different things. The callback is simply a way to run code before and after the role record is created/destroyed, it is not used to control whether the mutation code within is run.

    Some options:

    1. Add logic to your model to test if it can_remove_role?(:role) and then test that in your controller before making the change.
    2. If you are saving from a form, you can make a validation on the model to check your condition. ie. The User model would be invalid if that was what changed. Check out the methods on Dirty for inspiration on how to see what did/will change https://api.rubyonrails.org/classes/ActiveModel/Dirty.html
    3. Use a policy in something like the Pundit gem or similar authorization package (which your program should have if it is to be used in a real environment) to wrap changing of roles. ie. in the Pundit example your UserPolicy would have a change_role? or similar policy where you define what is a legal role change for the @record and then call the authorize on it.

    Option 3 is nice, because it provides a DRY location to make more rules regarding what can and cannot be done with your Users. Perhaps do some searches for tutorials on how Pundit and Rolify can be used together.