Ask A Question


You’re not receiving notifications from this thread.

Pundit Scope and has_many through

Wouter van den Beld asked in Rails


I can use a little help to get on the right track.

I have 3 models

class User < ActiveRecord::Base
  has_many :associations
  has_many :items, through: :associations

class Item < ActiveRecord::Base
   has_many :associations
   has_many :users, through: :associations

class Association < ActiveRecord::Base
    belongs_to :user
    belongs_to :item

Now i want to allow my users only to view and edit the item if they have a link trough associations.
so in my ItemPolicy i have the following scope

 class Scope < Scope
    def resolve
     if user.admin?
        scope.where(:company_id =>

I setup my items_controller

def index
  @items = policy_scope(Item.includes(:company).all)
  authorize @items

and this works. i only see the items where i have a association. Now i want to prevent users to edit the urllike and still be able to view item 2 if there is no association.

So i setup my show in the controller:

def show
    @item = policy_scope(Item.find(params[:id]))
    authorize @item

but now i get undefined method `where' error. why does the same thing work for index and not for show?
any ideas?

also i would like your opinion if this is the right way to go.


I think that's because on the index you want an array of records, but on show you just want a single record.

When you pass in the array into policy_scope, it's going to call the .where(company_id: X) method on it. This works when you return Item.all but when you pass in just an Item record, that does not have a where method because it's a single instance of the Item class.

In your show action, you can change it to:

def show
    @item = Item.find(params[:id])
    authorize @item

And this will load the record and Pundit will know to authorize it against the right method in the policy without hitting the Scope.

Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 83,603+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.