Reputation: 1362
I am created new rails application and I want to restrict user actions based on only one condition like record can be editable by owner(created_by) and sub-owner(Added by owner). I have models like App, User and controller like AppController. In AppController I have more than one actions like index, create, show, update, delete. I have one policy like AppPolicy. Here I need to create only one method to verify all actions but by default each action requires another method like action_name? in policy class.
Example
Existing code:
class AppPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope
end
end
def action1?
record.users.include? (user)
end
def action2?
record.users.include? (user)
end
def action3?
record.users.include? (user)
end
end
From above code we can see a same condition reside in all methods. I need to use only one method to verify action1, action2, action3. I don't know this is possible or not in Pundit.
Upvotes: 2
Views: 1515
Reputation: 1022
I also just had this same problem.
Ive done it with an admin policy. In any controller action, do authorize [:admin, :user], :admin?
The first part tells Pundit what policy to use, the second which authorization method.
The policy class:
class Admin::UserPolicy
attr_reader :current_user, :model
def initialize(current_user, model)
@current_user = current_user
end
def admin?
@current_user.has_admin_privilege?('full_admin')
end
end
Upvotes: 0
Reputation: 1968
I know this is an old question but I just had the same problem.
I can think about 2 solutions:
When you know all the actions that could be called.
You can use define_method
, like this
[:action1?, :action2?].each do |m|
define_method(m) { record.users.include? (user) }
end
When you don't know all the actions. (this could be dangerous)
You can use a combination of method_missing
and respond_to_missing
. The latter is needed since pundit will call internally respond_to
before calling the corresponding method of the policy.
Example:
def method_missing(m, *args, &block)
record.users.include? (user)
end
def respond_to_missing?(method_name, include_private = false)
true #Here it would be better to add some conditions
end
Upvotes: 0
Reputation: 164
You can use cancan (or cancancan) gem rubygems link
You can create the ability configuration file with
rails g cancan:ability
The authorize!
method in your controller will raise an exception if the user is not able to perform the given action, so call it on before_action
callback.
Documentation here
Upvotes: -4