module ActionPolicy::Policy::Core
Core
policy API
Attributes
Public Class Methods
# File lib/action_policy/policy/core.rb, line 43 def included(base) base.extend ClassMethods # Generate a new class for each _policy chain_ # in order to extend it independently base.module_eval do @result_class = Class.new(ExecutionResult) # we need to make this class _named_, # 'cause anonymous classes couldn't be marshalled base.const_set(:APR, @result_class) end end
NEXT_RELEASE: deprecate `record` arg, migrate to `record: nil`
# File lib/action_policy/policy/core.rb, line 78 def initialize(record = nil, *) @record = record end
Public Instance Methods
This method performs the rule call. Override or extend it to provide custom functionality (such as caching, pre checks, etc.)
# File lib/action_policy/policy/core.rb, line 108 def __apply__(rule) = public_send(rule) # Wrap code that could modify result # to prevent the current result modification def with_clean_result # :nodoc: was_result = @result yield @result ensure @result = was_result end # Returns a result of applying the specified rule to the specified record. # Under the hood a policy class for record is resolved # (unless it's explicitly set through `with` option). # # If record is `nil` then we uses the current policy. def allowed_to?(rule, record = :__undef__, **options) if (record == :__undef__ || record == self.record) && options.empty? __apply__(resolve_rule(rule)) else policy_for(record: record, **options).then do |policy| policy.apply(policy.resolve_rule(rule)) end end end # An alias for readability purposes def check?(*args, **hargs) = allowed_to?(*args, **hargs) # Returns a rule name (policy method name) for activity. # # By default, rule name is equal to activity name. # # Raises ActionPolicy::UknownRule when rule is not found in policy. def resolve_rule(activity) raise UnknownRule.new(self, activity) unless respond_to?(activity) activity end # Return annotated source code for the rule # NOTE: require "method_source" and "unparser" gems to be installed. # Otherwise returns empty string. def inspect_rule(rule) = PrettyPrint.print_method(self, rule) # Helper for printing the annotated rule source. # Useful for debugging: type `pp :show?` within the context of the policy # to preview the rule. def pp(rule) with_clean_result do # We need result to exist for `allowed_to?` to work correctly @result = self.class.result_class.new(self.class, rule) header = "#{self.class.name}##{rule}" source = inspect_rule(rule) $stdout.puts "#{header}\n#{source}" end end end end end
# File lib/action_policy/policy/core.rb, line 100 def allow! result&.load true throw :policy_fulfilled end
Returns a result of applying the specified rule to the specified record. Under the hood a policy class for record is resolved (unless it's explicitly set through `with` option).
If record is `nil` then we uses the current policy.
# File lib/action_policy/policy/core.rb, line 125 def allowed_to?(rule, record = :__undef__, **options) if (record == :__undef__ || record == self.record) && options.empty? __apply__(resolve_rule(rule)) else policy_for(record: record, **options).then do |policy| policy.apply(policy.resolve_rule(rule)) end end end
Returns a result of applying the specified rule (true of false). Unlike simply calling a predicate rule (`policy.manage?`), `apply` also calls pre-checks.
# File lib/action_policy/policy/core.rb, line 85 def apply(rule) @result = self.class.result_class.new(self.class, rule) catch :policy_fulfilled do result.load __apply__(rule) end result.value end
An alias for readability purposes
# File lib/action_policy/policy/core.rb, line 136 def check?(*args, **hargs) = allowed_to?(*args, **hargs) # Returns a rule name (policy method name) for activity. # # By default, rule name is equal to activity name. # # Raises ActionPolicy::UknownRule when rule is not found in policy. def resolve_rule(activity) raise UnknownRule.new(self, activity) unless respond_to?(activity) activity end # Return annotated source code for the rule # NOTE: require "method_source" and "unparser" gems to be installed. # Otherwise returns empty string. def inspect_rule(rule) = PrettyPrint.print_method(self, rule) # Helper for printing the annotated rule source. # Useful for debugging: type `pp :show?` within the context of the policy # to preview the rule. def pp(rule) with_clean_result do # We need result to exist for `allowed_to?` to work correctly @result = self.class.result_class.new(self.class, rule) header = "#{self.class.name}##{rule}" source = inspect_rule(rule) $stdout.puts "#{header}\n#{source}" end end end end
# File lib/action_policy/policy/core.rb, line 95 def deny! result&.load false throw :policy_fulfilled end
Return annotated source code for the rule NOTE: require “method_source” and “unparser” gems to be installed. Otherwise returns empty string.
# File lib/action_policy/policy/core.rb, line 152 def inspect_rule(rule) = PrettyPrint.print_method(self, rule) # Helper for printing the annotated rule source. # Useful for debugging: type `pp :show?` within the context of the policy # to preview the rule. def pp(rule) with_clean_result do # We need result to exist for `allowed_to?` to work correctly @result = self.class.result_class.new(self.class, rule) header = "#{self.class.name}##{rule}" source = inspect_rule(rule) $stdout.puts "#{header}\n#{source}" end end end
Helper for printing the annotated rule source. Useful for debugging: type `pp :show?` within the context of the policy to preview the rule.
# File lib/action_policy/policy/core.rb, line 157 def pp(rule) with_clean_result do # We need result to exist for `allowed_to?` to work correctly @result = self.class.result_class.new(self.class, rule) header = "#{self.class.name}##{rule}" source = inspect_rule(rule) $stdout.puts "#{header}\n#{source}" end end
Returns a rule name (policy method name) for activity.
By default, rule name is equal to activity name.
Raises ActionPolicy::UknownRule when rule is not found in policy.
# File lib/action_policy/policy/core.rb, line 143 def resolve_rule(activity) raise UnknownRule.new(self, activity) unless respond_to?(activity) activity end