Pundit scopes + Inherited Resources
Created by: onemanstartup
Hi. I took your code and slightly modified, please look at this. I needed to use additional scope for collection after it was authorized, so only method i came up is path inherited resources. One problem is verification of policies don't work yet. What do you think about this approach? Can be it done differently or not at all? It seems odd for me to keep all scopes in policies.
module Accessable
module ::InheritedResources
module BaseHelpers
def end_of_association_chain
if association_chain.is_a?(ActiveRecord::Relation)
apply_scopes_if_available(association_chain)
elsif chain = association_chain.last
if method_for_association_chain
apply_scopes_if_available(chain.send(method_for_association_chain))
else
chain
end
else
apply_scopes_if_available(resource_class)
end
end
end
end
def self.included base
base.send :include, Pundit
base.class_eval do
before_filter :authorize_resource
def policy_scope scope
Pundit.policy_scope!(current_user, scope)
end
def policy record
Pundit.policy!(current_user, record)
end
end
end
protected
# Authorize resource, see Policies.
def authorize_resource
case action_name
when build_resources_authorized
authorize controlled_access_build_resource
when resources_authorized
authorize controlled_access_resource
when collection_authorized
@association_chain = policy_scope(resource_class)
else
authorize resource_class
end
end
private
def controlled_access_collection c
policy_scope c
end
def collection_authorized
/index/
end
def build_resources_authorized
/new|create/
end
def resources_authorized
/edit|update|show|destroy/
end
def controlled_access_build_resource
return build_resource if respond_to?(:build_resource)
resource_class.new params[resource_class.to_s.to_sym]
end
def controlled_access_resource
return resource if respond_to?(:resource)
resource_class.find(params[:id])
end
end
class ArticlesController < InheritedResources::Base
include Accessable
# after_action :verify_policy_scoped, :only => :index
respond_to :html
respond_to :rss, only: :index
protected
def collection
@articles ||= end_of_association_chain.page(params[:page]).per(10).order(:id)
end
def build_resource_params
[params.fetch(resource_instance_name, {}).permit(:title, :short_description, :body, :tag_list, :meta_description, :meta_keywords, :meta_title)]
end
end