简体   繁体   中英

Rails pundit scope does not return from or block

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? || validation_not_finished? it will make the whole block true instead of return false and skip everything which is after ||?

|| => 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM