# Rule Aliases Action Policy allows you to add rule aliases. It is useful when you rely on _implicit_ rules in controllers. For example: ```ruby class PostsController < ApplicationController before_action :load_post, only: [:edit, :update, :destroy] private def load_post @post = Post.find(params[:id]) # depending on action, an `edit?`, `update?` or `destroy?` # rule would be applied authorize! @post end end ``` In your policy, you can create aliases to avoid duplication: ```ruby class PostPolicy < ApplicationPolicy alias_rule :edit?, :destroy?, to: :update? end ``` **NOTE**: `alias_rule` is available only if you inherit from `ActionPolicy::Base` or include `ActionPolicy::Policy::Aliases` into your `ApplicationPolicy`. **Why not just use Ruby's `alias`?** An alias created with `alias_rule` is resolved at _authorization time_ (during an `authorize!` or `allowed_to?` call), and it does not add an alias method to the class. That allows us to write tests easier, as we should only test the rule, not the alias–and to leverage [caching](caching.md) better. By default, `ActionPolicy::Base` adds one alias: `alias_rule :new?, to: :create?`. ## Default rule You can add a _default_ rule–the rule that would be applied if the rule specified during authorization is missing (like a "wildcard" alias): ```ruby class PostPolicy < ApplicationPolicy # For an ApplicationPolicy, makes :manage? match anything that is # not :index?, :create? or :new? default_rule :manage? # If you want manage? to catch really everything, place this alias #alias_rule :index?, :create?, :new?, to: :manage? def manage? # ... end end ``` Now when you call `authorize! post` with any rule not defined in the policy class, the `manage?` rule is applied. Note that `index?` `create?` and `new?` are already defined in the [superclass by default](custom_policy.md) (returning `false`) - if you want the same behaviour for *all* actions, define aliases like in the example above (commented out). By default, `ActionPolicy::Base` sets `manage?` as a default rule. ## Aliases and Private Methods Rules in `action_policy` can only be public methods. Trying to use a private method as a rule will raise an error. Thus, aliases can also only point to public methods. ## Rule resolution with subclasses Here's the order in which aliases and concrete rule methods are resolved in regards to subclasses: 1. If there is a concrete rule method on the subclass, this is called, else 2. If there is a matching alias then this is called, else * When aliases are defined on the subclass they will overwrite matching aliases on the superclass. 3. If there is a concrete rule method on the superclass, then this is called, else 4. If there is a default rule defined, then this is called, else 5. `ActionPolicy::UnknownRule` is raised. Here's an example with the expected results: ```ruby class SuperPolicy < ApplicationPolicy default_rule :manage? alias_rule :update?, :destroy?, :create?, to: :edit? def manage? end def edit? end def index? end end class SubPolicy < AbstractPolicy default_rule nil alias_rule :index?, :update?, to: :manage? def create? end end ``` Authorizing against the SuperPolicy: * `update?` will resolve to `edit?` * `destroy?` will resolve to `edit?` * `create?` will resolve to `edit?` * `manage?` will resolve to `manage?` * `edit?` will resolve to `edit?` * `index?` will resolve to `index?` * `something?` will resolve to `manage?` Authorizing against the SubPolicy: * `index?` will resolve to `manage?` * `update?` will resolve to `manage?` * `create?` will resolve to `create?` * `destroy?` will resolve to `edit?` * `manage?` will resolve to `manage?` * `edit?` will resolve to `edit?` * `index?` will resolve to `manage?` * `something?` will raise `ActionPolicy::UnknownRule`