4

I've had a long break from my 2 years of effort in trying to learn how to use pundit in my rails app. I'm back and trying to learn how to use pundit.

I've made a completely new rails 5 app and installed pundit.

I have a user resource, an application policy and a user policy. Each has:

Users controller:

def index
    # @users = User.all
    @users = policy_scope(User)
  end

Application Policy

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end

  def index?
    true
  end

  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    false
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

  def scope
    Pundit.policy_scope!(user, record.class)
  end

  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user = user
      @scope = scope
    end

    def resolve
      scope
    end
  end
end

User policy

class UserPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      scope.where(user: user)
    end
  end


end

Then in my user index, I'm trying to follow the instructions in the pundit gem docs, by doing:

<% policy_scope(@users).each do |user| %>

I get this error:

PG::UndefinedColumn: ERROR:  column users.user does not exist
LINE 1: SELECT "users".* FROM "users" WHERE "users"."user" = '566119...
                                            ^
: SELECT "users".* FROM "users" WHERE "users"."user" = '566119d2-54d8-4ab2-b7c5-f17c80b517f3' AND "users"."user" = '566119d2-54d8-4ab2-b7c5-f17c80b517f3'

Can anyone see how I'm getting off to the wrong start? I haven't even tried to define my scope in the way I want to yet, but it isn't working at this point.

Mel
  • 2,481
  • 26
  • 113
  • 273

1 Answers1

1
class UserPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      scope.where(user: user)
    end
  end
end

scope.where means the User class (user.where), because it's inside the user policy.

The user value is the current user, inherited by the application scope.

The scope example that you posted i'm guessing that you want to show only current user records. Then you can do the following as the comment above:

scope.where(id: user.try(:id))

Also because you have defined a scope in the controller

def index
  # @users = User.all
  @users = policy_scope(User)
end

You don't need to define another one in the view.

 <% policy_scope(@users).each do |user| %>

It's one or the other. In the view you can simply do users.each do....

Alex A
  • 156
  • 1
  • 10