I defines a Pundit policy "CompanyPolicy" as stated in the documentation , the scopez gives the expected results ( on :index ) but I get an exception trying to use the company model instance :
*** NameError Exception: undefined local variable or method `company' for #<CompanyPolicy:
here is the CompanyPolicy.rb
class CompanyPolicy < ApplicationPolicy
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user.system_admin?
scope.all
else
Company.none
end
end
end
def new?
user.system_admin? ? true : false
end
def edit?
user.system_admin? ? true : false
end
def show?
user.system_admin? ? true : false
end
def destroy?
internal_name = Rails.application.secrets.internal_company_short_name
# do not destroy the internal company record
user.system_admin? && (company[:short_name] != internal_name ) ? true : false
end
end
and I check it from the Company controller
def destroy
authorize @company
#@company.destroy
....
end
why (company[:short_name] is wrong ?
If I look into the Pundit doc , the example with the PostPolicy , scope and post.published is similar ...
class PostPolicy < ApplicationPolicy
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user.admin?
scope.all
else
scope.where(:published => true)
end
end
end
def update?
user.admin? or not post.published?
end
end
Take a look into documentation:
Pundit makes the following assumptions about this class:
- The class has the same name as some kind of model class, only suffixed with the word "Policy".
- The first argument is a user. In your controller, Pundit will call the current_user method to retrieve what to send into this argument
- The second argument is some kind of model object, whose authorization you want to check. This does not need to be an ActiveRecord or even an ActiveModel object, it can be anything really.
- The class implements some kind of query method, in this case update?. Usually, this will map to the name of a particular
controller action.That's it really.
Usually you'll want to inherit from the application policy created by the generator, or set up your own base class to inherit from:
class PostPolicy < ApplicationPolicy def update? user.admin? or not record.published? end end
In the generated ApplicationPolicy, the model object is called
record
.