0

In my app I want to prevent the user from taking the Legal Test again. To do so I'm using pundit authorization with below policy:

class TestResultPolicy < ApplicationPolicy
  def new?
    !passed? || validation_not_finished?
  end

  private

  def passed?
    user.test_results.where.not(test_result: 'passed').any?
  end
end

Which I use in below controller:

class TestResultsController < ApplicationController
  before_action :randomize_questions, only: %i[new create]

  def new
    @test_result = TestResult.new
    authorize @test_result
  end

  def create
    #some actions
  end

The problem is when user already passed the test he still have ability to take another test (is able to visit test_results_path). If I just leave !passed? everything will work as it should but if I add OR condition || validation_not_finished? it will make the whole block true instead of return false and skip everything which is after || ?

mr_muscle
  • 2,536
  • 18
  • 61

1 Answers1

0

|| => Called Logical OR Operator. If any of the two operands are true, then the condition becomes true.

> false || false
=> false
> false || true
=> true
> true || false
=> true
> true || true
=> true

you can explicitly return false when user have failed test, so that it will skip check for validation_not_finished?

class TestResultPolicy < ApplicationPolicy
  def new?
    return false if failed?
    validation_not_finished?
  end

  private

  def failed?
    user.test_results.where.not(test_result: 'passed').any?
  end
end
Sampat Badhe
  • 8,710
  • 7
  • 33
  • 49