lib/pundit/resource.rb in pundit-resources-1.0.0 vs lib/pundit/resource.rb in pundit-resources-1.0.1

- old
+ new

@@ -12,59 +12,75 @@ module ClassMethods def records(options = {}) warn_if_show_defined context = options[:context] + context[:policy_used]&.call Pundit.policy_scope!(context[:current_user], _model_class) end private def warn_if_show_defined policy_class = Pundit::PolicyFinder.new(_model_class.new).policy! - if policy_class.method_defined?(:show?) + if policy_class.instance_methods(false).include?(:show?) puts "WARN: pundit-resources does not use the show? action." puts " #{policy_class::Scope} will be used instead." end end end protected + def can(method) + context[:policy_used]&.call + policy.public_send(method) + end + def current_user context&.[](:current_user) end def policy Pundit.policy!(current_user, _model) end def authorize_create_or_update action = _model.new_record? ? :create : :update - not_authorized!(action) unless policy.public_send(:"#{action}?") + not_authorized!(action) unless can :"#{action}?" end def authorize_destroy - not_authorized! :destroy unless policy.destroy? + not_authorized! :destroy unless can :destroy? end def records_for(association_name, options={}) - association_reflection = _model.class.reflect_on_association(association_name) + relationships = self.class._relationships. + values. + select { |r| r.relation_name(context: @context) == association_name }. + uniq(&:class) - if association_reflection.macro == :has_many + unless relationships.count == 1 + raise "Can't infer relationship type for #{association_name}" + end + + relationship = relationships.first + + case relationship + when JSONAPI::Relationship::ToMany records = _model.public_send(association_name) policy_scope = Pundit.policy_scope!( context[:current_user], - association_reflection.class_name.constantize + records ) records.merge(policy_scope) - elsif [:has_one, :belongs_to].include?(association_reflection.macro) + when JSONAPI::Relationship::ToOne record = _model.public_send(association_name) # Don't rely on policy.show? being defined since it isn't used for # show actions directly and should always have the same behaviour. - if record && show?(Pundit.policy!(context[:current_user], record)) + if record && show?(Pundit.policy!(context[:current_user], record), record.id) record else nil end end @@ -75,10 +91,10 @@ def not_authorized!(action) options = { query: action, record: _model, policy: policy } raise Pundit::NotAuthorizedError, options end - def show?(policy) - policy.scope.where(id: policy.record.id).exists? + def show?(policy, record_id) + policy.scope.where(id: record_id).exists? end end end