Search code examples
ruby-on-railsruby-on-rails-5pundit

Using scopes in my Pundit policy (Rails 5)


How to use scopes, defined in the model, in my Pundit policy?

In my model I have a scope:

scope :published, ->{ where.not(published_at: nil )}

And in my Pundit policy I have

class CompanyPolicy < ApplicationPolicy
    def index?
        true
    end
    def create?
        user.present?
    end
    def new?
        true
    end
    def show?
        true
    end
    def update?
      user.present? && user == record.user
    end
end

How can I use my scope in the Pundit policy? I would like to show it only if it's "published", something like this, which doesn't work at the moment:

class CompanyPolicy < ApplicationPolicy
    def show
       record.published?
    end
end

Solution

  • Scopes are Class methods, you can't call them on instances.

    You have to define a published? instance method too:

    def published?
      published_at.present?
    end
    

    You could use the scope if you ask if the record exists on the given scope with:

    User.published.exists?(user.id)
    

    And it will return true if the scope includes the user id, but I wouldn't recommend that, it requires an extra query to the database to get something that you can know from the user instance you already have.