Skip to content

Instantly share code, notes, and snippets.

@OfTheDelmer
Created August 27, 2015 19:01
Show Gist options
  • Select an option

  • Save OfTheDelmer/4ae976a08dbea367f0a8 to your computer and use it in GitHub Desktop.

Select an option

Save OfTheDelmer/4ae976a08dbea367f0a8 to your computer and use it in GitHub Desktop.

Revisions

  1. OfTheDelmer created this gist Aug 27, 2015.
    79 changes: 79 additions & 0 deletions policy_calling.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@

    A `PolicyResult` class to help collect the `status` and `message` from a policy check

    ```ruby
    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:

    ```ruby
    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
    ```