0

The current user i'm on isn't an admin, however when I hit the new action of the posts controller, I'm able to see it. Why is this? How do I use pundit properly?

From the rails console: 2.1.2 :011 > u.admin? => false

post_policy.rb:

class PostPolicy < ApplicationPolicy

attr_reader :current_user, :model

def initialize(current_user, model)
  @current_user = current_user
  @post = model
end

def show?
@post.public?
end

def new?
    @current_user.admin?
end

def create?
    @current_user.admin?
end

def edit?
    @current_user.admin?
end

def update?
  @current_user.admin?
end

def destroy?
  @current_user.admin?
end

end

posts_controller.rb:

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
  end

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
  end

  # POST /posts
  # POST /posts.json
  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /posts/1
  # PATCH/PUT /posts/1.json
  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def post_params
      params.require(:post).permit(:visible_title, :html_title, :meta_description, :meta_keywords, :url_slug, :partial_name, :author, :post_date, :public, :category, :tags)
    end
end

posts/show.html.erb:

standard file printing out the contents of the post.

Pavan Katepalli
  • 2,372
  • 4
  • 29
  • 52

1 Answers1

2

You have created a policy file that defines which user may take which action.

However, you do not call the authorization anywhere.

def new
  @post = Post.new
  authorize @post
end

would perform the authorization of the post object, using the current user, and asking whether new was allowed.

This is explained in detail in the official readme.

Nils Landt
  • 3,104
  • 18
  • 18