lib/clean_model/attribute.rb
module CleanModel
class Attribute
attr_reader :name, :options
def initialize(name, options={})
@name = symbolize(name)
@options = options
end
def validate!(value)
raise InvalidTypeAssignment.new(name, value) unless value.is_a? klass
end
def transform(value)
if @options[:transformation]
@options[:transformation].call(value)
elsif value.is_a?(Hash) && klass.new.respond_to?(:assign_attributes)
obj = klass.new
obj.assign_attributes value
obj
elsif value.is_a?(Array) && collection_class.instance_methods.include?(:assign_attributes)
value.map do |v|
if v.is_a? collection_class
v
else
obj = collection_class.new
obj.assign_attributes v
obj
end
end
else
value
end
end
def assign_default(model)
default_value = @options[:default].is_a?(Proc) ? @options[:default].call : @options[:default]
model.send("#{@name}=", default_value) if !default_value.nil? && model.respond_to?("#{@name}=")
end
private
def klass
@options[:class_name].to_s.classify.constantize
end
def collection_class
@options[:collection].to_s.classify.constantize
end
def symbolize(text)
text.is_a?(String) ? text.to_s.underscore.parameterize('_').to_sym : text
end
end
end