Skip to main content

How do I apply a Pundit Policy to Index?

Rails • Asked by Rich Smith
I'd like to have an index page show only the associated (from the parent, location) records, and allow only users that own those records to see the index.  I am really struggling with this concept of scopes and would appreciate any help.

Here's where I'm at:
# New Document
Here's where I'm at:

#### Models

```
User
  has_one :business
  has_many :locations, :through => :business
end

Business
  belongs_to :user
  has_many :locations
end

Location
  extend FriendlyId
  belongs_to :business
  has_one :user, :through => :business
  has_many :sites, dependent: :destroy
  friendly_id :custom_url, use: :slugged
end

Site
  belongs_to :location
end

```

#### routes.rb
```
 resources :locations do
    resources :sites
  end
```

#### sites_controller.rb
```
class SitesController < ApplicationController
  before_action :set_site, only: [:show, :edit, :update, :destroy]
  before_action :set_location, only: [:new, :show, :edit, :index, :update, :destroy]
  
  
  def index
    authorize Site
    @sites = @location.sites.all
  end

  private
    def set_site
      @site = Site.find(params[:id])
    end
    def set_location
      @location = Location.friendly.find(params[:location_id])
    end
    def site_params
      params.require(:site).permit(:location_id, :site, :url, :review_site_id, :number_of_reviews, :average_rating, :extra_data)
    end
end
  
  ```

#### site_policy.rb

```
class SitePolicy < ApplicationPolicy
    class Scope
      attr_reader :user, :scope
  
      def initialize(user, scope)
        @user  = user
        @scope = scope
      end
  
      def resolve
        if user.has_role? :admin
          scope.all
        else
          scope.where(location.user)
        end
      end
    end

  def index? 
    return true if user.present? and user.has_role? :admin
  end
  ...
```


Any help or pointers at all would be super appreciated, I am really struggling wrapping my head around Pundit Scopes, but am keenly aware that I need them to get an index page to work. 





Formatted...

I'd like to have an index page show only the associated (from the parent, location) records, and allow only users that own those records to see the index.  I am really struggling with this concept of scopes and would appreciate any help.

Here's where I'm at:

Models

User
  has_one :business
  has_many :locations, :through => :business
end

Business
  belongs_to :user
  has_many :locations
end

Location
  extend FriendlyId
  belongs_to :business
  has_one :user, :through => :business
  has_many :sites, dependent: :destroy
  friendly_id :custom_url, use: :slugged
end

Site
  belongs_to :location
end


routes.rb


 resources :locations do
    resources :sites
  end


sites_controller.rb


class SitesController < ApplicationController
  before_action :set_site, only: [:show, :edit, :update, :destroy]
  before_action :set_location, only: [:new, :show, :edit, :index, :update, :destroy]
  
  
  def index
    authorize Site
    @sites = @location.sites.all
  end

  private
    def set_site
      @site = Site.find(params[:id])
    end
    def set_location
      @location = Location.friendly.find(params[:location_id])
    end
    def site_params
      params.require(:site).permit(:location_id, :site, :url, :review_site_id, :number_of_reviews, :average_rating, :extra_data)
    end
end
  

site_policy.rb



class SitePolicy < ApplicationPolicy
    class Scope
      attr_reader :user, :scope
  
      def initialize(user, scope)
        @user  = user
        @scope = scope
      end
  
      def resolve
        if user.has_role? :admin
          scope.all
        else
          scope.where(location.user)
        end
      end
    end

  def index? 
    return true if user.present? and user.has_role? :admin
  end
  ...



Any help or pointers at all would be super appreciated, I am really struggling wrapping my head around Pundit Scopes, but am keenly aware that I need them to get an index page to work. 

Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 27,623+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.