Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge validators into a single composite #40

Open
octopusinvitro opened this issue Feb 5, 2018 · 0 comments
Open

Merge validators into a single composite #40

octopusinvitro opened this issue Feb 5, 2018 · 0 comments

Comments

@octopusinvitro
Copy link
Contributor

octopusinvitro commented Feb 5, 2018

See our contributing guides.

There are now several validator classes that share validations, and these validations are done in a similar way.

Remove this repetition by moving all validator methods to its own file, and then replace the validator classes with a single composite class that picks the validations it needs.

Then the Validation class doesn't need to be exposed and can be a private class of the composite.

For example:

require 'utils'

class Validators
  def initialize(data)
    @data = data
  end

  def validate_data
    :missing_data unless data
  end

  def validate_type
    :invalid_donation_type unless data&.type &&
                                  VALID_TYPES.values.include?(data.type)
  end

  def validate_amount
    :invalid_amount unless data&.amount && utils.number?(data.amount) &&
                           utils.number(data.amount).positive?
  end

  # ... etc.

  private

  attr_reader :data
end

and the composite class:

# ...
require_relative 'validators'

module DonationSystem
  class Validator
    def self.execute(data, list)
      new(data, list).execute
    end

    def initialize(data, list)
      @data = data
      @list = list
    end

    def execute
      validation = Validation.new
      validators = Validators.new(data)
      list.each { |item| validation << validators.send(:"validate_#{item}") }
      validation
    end

    private

    attr_reader :data, :list

    class Validation
      attr_reader :errors

      def initialize
        @errors = []
      end

      def <<(error)
        errors << error if error
      end

      def okay?
        errors.empty?
      end
    end
  end
end

Then, whenever a validator class is used, it can be replaced with this composite:

    def validation
      list = [:data, :type, :amount, :currency, :token, :email, :method]
      @validation ||= Validator.execute(data, list)
    end

It may be tempting to use Validators as an included module, but that introduces an inheritance pattern that is not needed here, as different validators will require a different list of validator methods.

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

No branches or pull requests

1 participant