Skip to content

Instantly share code, notes, and snippets.

@voxxit
Created June 4, 2009 16:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save voxxit/123692 to your computer and use it in GitHub Desktop.
Save voxxit/123692 to your computer and use it in GitHub Desktop.
Allows you to require parameters from hashes in your methods
# A module which adds support for attribute validation and requirements
# directly to the Hash object in Ruby. Very useful for methods which
# require a ton of attributes.
#
# ==== Example Usage
#
# require 'attribute_support'
#
# class Klass
# def renew_domain(attributes = {})
# attributes.valid_attributes(:domain_name, :number_of_months)
# attributes.require!(:domain_name)
#
# attributes.valid_type?(:domain_name, String)
# attributes.valid_type?(:number_of_months, Integer) unless attributes[:number_of_months].nil?
# end
# end
module AttributeSupport #:nodoc:
# Defines the attributes which are considered valid for the hash. If an
# invalid or unknown attribute is included, an ArgumentError is raised.
#
# ==== Examples
#
# >> { :name => "Rob", :years => "28" }.valid_attributes(:name, :age)
# ArgumentError: Unknown attributes(s): years
#
# >> { :name => "Rob", :age => "28" }.valid_attributes(:name, :age)
# => nil
def valid_attributes(*valid_attrs)
unknown_attrs = keys - [valid_attrs].flatten
raise ArgumentError.new("Unknown attributes(s): #{unknown_attrs.join(", ")}") unless unknown_attrs.empty?
end
# Checks to make sure that all required attributes are included in the
# hash. If a required attribute is missing, an ArgumentError is raised.
#
# ==== Examples
#
# >> { :name => "Josh", :age => "24" }.requires!(:name, :years)
# ArgumentError: Missing required parameter: years
#
# >> { :name => "Josh", :age => "24" }.requires!(:name, :age)
# => nil
def requires!(*params)
params.each do |param|
raise ArgumentError.new("Missing required parameter: #{param}") unless self.has_key?(param)
end
end
# Ensures that the specified key in the hash matches one of the
# types provided. If it doesn't, a TypeError is raised.
#
# ==== Examples
#
# >> { :name => "Josh" }.valid_type?(:name, Integer, Date)
# TypeError: Object associated with :name attribute must be one of: Integer, Date
#
# >> { :name => "Josh" }.valid_type?(:name, String)
# => nil
def valid_type?(key, *types)
types = [*types]
unless types.any? { |type| self[key].is_a?(type) }
raise TypeError.new("Object associated with :#{key.to_s} attribute must be one of: #{types.join(", ")}")
end
end
end
class Hash #:nodoc:
include AttributeSupport
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment