lib/dato/local/items_repo.rb in dato-0.1.17 vs lib/dato/local/items_repo.rb in dato-0.1.18

- old
+ new

@@ -3,16 +3,17 @@ require 'dato/local/item' module Dato module Local class ItemsRepo - attr_reader :entities_repo, :collections_by_type + attr_reader :entities_repo, :collections_by_type, :item_type_methods def initialize(entities_repo) @entities_repo = entities_repo @collections_by_type = {} @items_by_id = {} + @item_type_methods = {} build_cache! end def find(id) @@ -27,37 +28,57 @@ end end private - def item_type_key(item_type) - api_key = item_type.api_key - if item_type.singleton - [api_key.to_sym, true] - else - [api_key.pluralize.to_sym, false] + def build_cache! + build_item_type_methods! + build_collections_by_type! + end + + def build_item_type_methods! + @item_type_methods = {} + + singleton_keys = singleton_item_type_entities.map(&:api_key) + collection_keys = collection_item_type_entities.map(&:api_key) + .map(&:pluralize) + + clashing_keys = singleton_keys & collection_keys + + item_type_entities.each do |item_type| + singleton = item_type.singleton + pluralized_api_key = item_type.api_key.pluralize + method = singleton ? item_type.api_key : pluralized_api_key + + if clashing_keys.include?(pluralized_api_key) + suffix = singleton ? 'instance' : 'collection' + method = "#{method}_#{suffix}" + end + + @item_type_methods[item_type] = [method.to_sym, singleton] end end - def build_cache! + def build_collections_by_type! item_type_entities.each do |item_type| - key, singleton = item_type_key(item_type) - @collections_by_type[key] = if singleton + method, singleton = item_type_methods[item_type] + + @collections_by_type[method] = if singleton nil else ItemCollection.new end end item_entities.each do |item_entity| item = Item.new(item_entity, self) + method, singleton = item_type_methods[item_entity.item_type] - key, singleton = item_type_key(item_entity.item_type) if singleton - @collections_by_type[key] = item + @collections_by_type[method] = item else - @collections_by_type[key].push item + @collections_by_type[method].push item end @items_by_id[item.id] = item end end @@ -68,15 +89,31 @@ def item_entities entities_repo.find_entities_of_type('item') end + def singleton_item_type_entities + item_type_entities.select(&:singleton) + end + + def collection_item_type_entities + item_type_entities - singleton_item_type_entities + end + def method_missing(method, *arguments, &block) if collections_by_type.key?(method) && arguments.empty? collections_by_type[method] else super end + rescue NoMethodError + message = [] + message << "Undefined method `#{method}`" + message << 'Available DatoCMS collections/items:' + message += collections_by_type.map do |key, _value| + "* .#{key}" + end + raise NoMethodError, message.join("\n") end class ItemCollection < Array def each(&block) if block && block.arity == 2