0

I'm using the Pundit gem for the user authorizations in my Rails project. The Edit function works as I expected, just user admin and whoever created the review is able to update it. However, I can't delete them with the pundit set up.

Here's my Reviews Controller:

class ReviewsController < ApplicationController
  before_action :set_review, only: [:show, :edit, :update, :destroy]
  
  def index
    @reviews = Review.all
  end

  def new
    @review = Review.new
  end

  def create
    @review = Review.new(review_params)
    @review.user_id = current_user.id
    if @review.save
      redirect_to review_path(@review), :alert => "Awesome! Here's your small review!"
    else
      error_messages(@review)
      render 'new' 
    end
  end

  def show
  end

  def edit
     authorize @review
  end

  def update
    if @review.update(review_params)
      redirect_to review_path(@review), :alert => "That's a good update!"
    else 
      error_messages(@review) 
      render 'edit'
    end  
  end

  def destroy
    authorize @review
    @review.destroy
    redirect_to reviews_path, :alert => "We'll miss that review."    
  end

  private

    def set_review
      @review = Review.find_by(id: params[:id])
    end 

    def review_params
      params.require(:review).permit(:title, :content)
    end
  
end

The Application Policy looks like this:

class ApplicationPolicy 
  attr_reader :user, :record

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

  def index?
    false
  end

  def show?
    false
  end

  def create?
    false
  end

  def create?
    new?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    destroy?
  end

  class Scope
    attr_reader :user, :scope

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

    def resolve
      scope.all
    end
  end
end

And here's my customized Review Policy file:

class ReviewPolicy < ApplicationPolicy
  
  def edit?
    user.admin? || record.user == user
  end

  def destroy?
    user.admin? || record.user == user
  end
end

In case you're wondering, I created the user_not_authorized helper method. My Application Controller looks like this.

class ApplicationController < ActionController::Base
    include Pundit
    rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
    protect_from_forgery with: :exception
    helper_method :current_user
    add_flash_types :info, :error, :warning

  def logged_in?
    !!current_user
  end

  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  def error_messages(obj)
    obj.errors.messages.each do |k,v|
      flash[:alert] = "#{k.to_s} #{v.first.to_s}"
    end
  end

  private 
  
    def user_not_authorized
      flash[:alert] = "Ooops sorry. You don't have access to this."
      redirect_to (request.referrer || root_path)
    end   
end

Hope my message is clear enough and would appreciate any help. Remember, '''user.admin? || record.user == user''' works for editing but the user admins and the review creators can't delete the reviews when applying the same methods.

Please let me know if any question.

Norbert
  • 103
  • 1
  • 11
  • What is the error message? Are you getting the falsh alert from the `user_not_authorized` method? – Clara Jul 04 '20 at 04:06
  • Yes, I'm receiving that same message. – Norbert Jul 04 '20 at 18:52
  • 1
    nothing seems incorrect about your setup, generally. are you attempting this as admin, or as the record.user? pundit can fail with the same message for config reason, but it really seems as though the user doesn't have adequate permissions. – trh Jul 05 '20 at 14:48
  • I'm trying as both with the same result. I'm starting all over again using Demise for user authorization and check if this time it will be correct. Thanks for the feedback regarding the setup though. – Norbert Jul 06 '20 at 16:44

0 Answers0