A PolicyResult class to help collect the status and message from a policy check
class PolicyResult
  attr_reader :message, :status
  def initialize(params)
    @status = params.fetch(:status, false)
    @message = params.fetch(:message, :no_message)
  end
endThen a refactor of a policy to return the status and optionally call a block with the full result
Usage:
class User < ActiveRecord::Base
...
  def verifiable?(&block)
    VerificationEligibilityPolicy.call &block
  end
  
end
current_user.verifiable? #=> true/false
current_user.verifiable? do |result|
  return nil if result.status
  redirect_to root_path, error: result.message
end
Which would have a refactor like the following:
class VerificationEligibilityPolicy
  MAX_ATTEMPTS = 2
  def self.call(params, &block)
    policy = new(params)
    result = policy.eligible?
    block.call result if block
    result.status
  end
  def initialize(params)
    @user = params.fetch(:user)
    @attempts = @user.attempts.recent
  end
  ##
  # checks that a user has not reached
  # max verification attempts or
  # that the user has waited past
  # the retry time window: 1.day
  def eligible?
    if !@user.identified_person?
      PolicyResult.new({message: "Create Identity"})
    elsif @attempts.count < MAX_ATTEMPTS
      next_time = @attempts.last.created_at + wait_time
      PolicyResult.new({message: "Please wait #{next_time}"})
    else
      PolicyResult.new({staus: true})
    end
  end
  private
  def wait_time
    1.day
  end
end
Also potentially only run the
blockif the status isfalse?