Your First Policy

Now let’s create a policy for our Product model. We’ll start simple and build up from there.

Generate a Policy

Run the policy generator:

Terminal window
$ bin/rails generate action_policy:policy Product

You should see:

Terminal window
create app/policies/product_policy.rb
create test/policies/product_policy_test.rb

Examine the Generated Policy

Open :

# frozen_string_literal: true
class ProductPolicy < ApplicationPolicy
# See https://actionpolicy.evilmartians.io/#/writing_policies
#
# def index?
# true
# end
#
# def update?
# # here we can access our context and record
# user.admin? || (user.id == record.user_id)
# end
end

The generator creates a skeleton with helpful comments showing example rule methods.

Write Your First Rules

Let’s add some real authorization rules. Replace the contents with:

# frozen_string_literal: true
class ProductPolicy < ApplicationPolicy
def index?
true
end
def show?
true
end
end

Understanding Policy Rules

Rule Naming Convention

Policy rules are predicate methods (methods ending with ?) that return true or false:

  • index? - Can the user list products?
  • show? - Can the user view a product?
  • create? - Can the user create a product?
  • update? - Can the user update a product?
  • destroy? - Can the user delete a product?

The Rule Context

Inside a policy rule, you have access to:

  • user - The current user (from current_user in your controller)
  • record - The object being authorized (the product in this case)

Try It in the Console

Let’s test our policy in the Rails console:

Terminal window
$ bin/rails console
store(dev)> policy = ProductPolicy.new(Product.first, user: nil)
=> #<ProductPolicy:0x...>
store(dev)> policy.index?
=> true
store(dev)> policy.show?
=> true

Our policy allows anyone to view products. Now we need to connect it to our controller!

What’s Next?

In the next section, we’ll learn how to use authorize! in our controller to enforce these policy rules.

Powered by WebContainers
Files
Preparing Environment
  • Preparing Ruby runtime
  • Prepare development database