Cancancan is a great gem to do simple permissions for your app. It's my go-to gem, especially when developing proof of concept products.

The Basics

There are two main things that you have to set up in order to get Cancancan to work

Setup abilities file

The first file you have to set up is the abilities file (found in app/model/ability.rb)

class Ability
  include CanCan::Ability

  def initialize(user)

    if user.has_role? :some_role_name
      can :manage, :all
    end
 end
end

Set up each controller for permissions

The format typically looks like this

class SomeObjectNameController < ApplicationController
  load_and_authorize_resource
end

Nested routes

If you're using nested routes and your route file looks like this

Rails.application.routes.draw do
  resource :parent_object do
    resource :child_object, shallow: true do
  end
  
  resource :child_object, shallow: true do
end

Assuming that you're trying to control access through the user_id, your abilities setup will typically look like this:

  if user.has_role? :user
    can :manage, ParentObject, user_id: user.id
    can :manage, ChildObject, parent_object: { user_id: user.id}
  end

The subsequent controller file would look like this

parent_object_controller.rb

class ParentController < ApplicationController
  load_and_authorize_resource
end

child_object_controller.rb

class PersonNotesController < ApplicationController
  load_and_authorize_resource :parent_object
  load_and_authorize_resource :child_object, through: :parent_object, shallow: true

Setting the load_and_authorize_resource shallow property to true allows you to access the object when it's not nested

Cancancan