Skip to content

Instantly share code, notes, and snippets.

@OfTheDelmer
Created August 27, 2015 19:01
Show Gist options
  • Save OfTheDelmer/4ae976a08dbea367f0a8 to your computer and use it in GitHub Desktop.
Save OfTheDelmer/4ae976a08dbea367f0a8 to your computer and use it in GitHub Desktop.

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

end

Then 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
@OfTheDelmer
Copy link
Author

Also potentially only run the block if the status is false?

@OfTheDelmer
Copy link
Author

HipChat comment: yield(result) if block_given?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment