Skip to content

Instantly share code, notes, and snippets.

@michaelminter
Created July 16, 2018 17:22
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 michaelminter/d0026bc3debcba647e5c3febd8cc26d0 to your computer and use it in GitHub Desktop.
Save michaelminter/d0026bc3debcba647e5c3febd8cc26d0 to your computer and use it in GitHub Desktop.
module Contents
class ExerciseWrapper < Contents::BaseWrapper
attribute :name, String
attribute :type
validate :name, presence: true
def to_fhir
{
one: :attribute_name,
two: {
a: :attribute_name,
b: :attribute_name
}
}
end
end
end
module Contents
class ValidationError < StandardError
attr_reader :object
def initialize(object)
@object = object
end
end
class BaseWrapper
attr_accessor :attributes, :errors
# rescue_from ValidationError, with: :validation_error
class << self
def attribute(attribute_name, klass = String, options = {})
@default_attributes[attribute_name.to_sym] = {}
@default_attributes[attribute_name.to_sym][:klass] = klass
@default_attributes[attribute_name.to_sym][:value] = options[:default].present? ? options[:default] : nil
end
def validate(attribute_name, options = {})
@rules = []
options.each do |option_name, option_value|
@rules << valid_attribute?(attribute_name, option_name, option_value)
end
end
def valid_attribute?(attribute_name, validation_name, validation_value)
attribute = @default_attributes[attribute_name.to_sym]
case validation_name.to_sym
when :presence
attribute[:value].present? ? true : raise(ValidationError, "#{attribute_name} must be present.")
when :includes
attribute[:value].includes?(validation_value) || raise(ValidationError, "#{attribute_name} must include #{validation_value}.")
end
end
end
def initialize(attributes) # TODO: accept JSON blob
@errors = []
@attributes = attributes
@default_attributes = {}
attributes.each do |attribute_name, attribute_value|
# Manually creates methods for both getter and setter and then
self.class.send(:define_method, "#{attribute_name}=".to_sym) do |value|
instance_variable_set("@#{attribute_name}", value)
end
self.class.send(:define_method, attribute_name.to_sym) do
instance_variable_get("@#{attribute_name}")
end
# Sends a message to the new setter with the attribute_value
self.send("#{attribute_name}=".to_sym, attribute_value)
end
end
def success?
errors.empty?
end
def data
# TODO: deep link to_fhir data with default attributes
# @default_attributes.merge(attributes.map{ |k, v| { k.to_sym => valueize(v[:klass], v[:value]) } })
end
def valueize(klass, value)
case klass
when String
value.to_s
when Integer
value.to_i
when Float
value.to_f
end
end
def validation_error(error)
errors << error
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment