Now, you can start creating your own policies; in our case, we would like to create a policy for the examples_controller created for the authentication mechanism:
# app/policies/example_policy.rb
class ExamplePolicy
attr_reader :user, :example_object
def initialize(user, example_object)
@user = user
@example_object = example_object
end
def index?
true
end
def show?
user&.created_at&.today? && example_object[:show] == true
end
end
Let's now move on to the different sections of our policy file:
def initialize(user, example_object)
@user = user
@example_object = example_object
end
The first argument is the user. In your controller, Pundit will call the current_user (the current_user method comes from the devise gem) method to retrieve what to send into this argument.
The second argument is a scope on which to perform a query. It will usually be an ActiveRecord class or an ActiveRecord::Relation, but it could be something else entirely.
Here, you allow any (even not logged-in) user to access this page:
def index?
true
end
Here, only logged-in users whose accounts were created today and when the value of the show key in the example_object hash is true will get access to this action.
def show?
user&.created_at&.today? && example_object[:show] == true
end
NOTE: In our case, example_object is neither ActiveRecord nor ActiveRecord::Relation instance, but a simple hash.
Now, let's customize the implementation of the controller:
class ExamplesController < ApplicationController
def index
authorize Hash, policy_class: ExamplePolicy
end
def show
example_object = { show: true }
authorize example_object, policy_class: ExamplePolicy
end
end
Great! Now, it is time to discuss the implementation of the index and show actions: To simplify this example, the value of example_object is hardcoded as Hash instance:
def index
authorize Hash, policy_class: ExamplePolicy
end
def show
example_object = { show: true }
authorize example_object, policy_class: ExamplePolicy
end
However, in most cases, it will be an ActiveRecord or ActiveRecord::Relation instance. We use the policy_class: ExamplePolicy because, without it, the Pundit would try to hit the HashPolicy file since our example_object is an instance of the Hash class, which is the default behavior of the Pundit gem.