lib/materialize/entity.rb in materialize-0.2.6 vs lib/materialize/entity.rb in materialize-0.3.0
- old
+ new
@@ -1,25 +1,80 @@
-# To test:
-# 1. Should be able to add extra arguments after attributes in a subclass
-# 2. Should throw an error if hash is not provided as FIRST argument
-
module Materialize
class Entity
+ include Utils
def self.wrap(entities_data)
entities_data.map { |entity_data| new(entity_data) }
end
+ attr_writer :__builder_info__
+
def initialize(attributes)
raise "Attributes must be a hash" unless attributes.is_a?(Hash)
attributes.each_pair do |key, value|
+ value = attempt_entity_conversion(key, value) if collection?(value)
instance_variable_set("@#{key}", value)
-
(class << self; self; end).class_eval do
attr_reader key.to_sym
end
end
+ end
+
+ private
+
+ # START REMARKS ---->
+
+ # These are here to allow for nested data coming from a data source via a repo.
+ # e.g.
+ # blog_post = {
+ # id: 1,
+ # title: 'TDD is dead (wait, what?)'
+ # ...
+ # comments: [...]
+ # }
+ #
+ # In this case, we need to queue a builder, which requires a repo and options (see repo & builder classes).
+ # WARNING:
+ # This should be avoided for deeply nested data, especially when the leaves look up extra data!
+
+
+ def __builder_info__
+ @__builder_info__ ||= {}
+ end
+
+ def repo
+ __builder_info__[:repo]
+ end
+
+ def options
+ __builder_info__[:options]
+ end
+
+ # ----> END REMARKS
+
+ def collection?(value)
+ value.is_a? Enumerable
+ end
+
+ def attempt_entity_conversion(key, value)
+ if class_exists?(covert_to_entity_class_name(key))
+ Module.const_get(builder_class_name_for(key)).build_all(value, repo, options)
+ else
+ value
+ end
+ end
+
+ def covert_to_entity_class_name(key)
+ "Entities::#{base_name_for(key)}"
+ end
+
+ def builder_class_name_for(key)
+ "#{base_name_for(key)}Builder"
+ end
+
+ def base_name_for(key)
+ key.to_s.singularize.split('_').collect(&:capitalize).join
end
end
end