lib/wcc/contentful/model.rb in wcc-contentful-1.0.8 vs lib/wcc/contentful/model.rb in wcc-contentful-1.1.0

- old
+ new

@@ -1,7 +1,9 @@ # frozen_string_literal: true +require_relative './model_api' + # This is the top layer of the WCC::Contentful gem. It exposes an API by which # you can query for data from Contentful. The API is only accessible after calling # WCC::Contentful.init! # # The WCC::Contentful::Model class is the base class for all auto-generated model @@ -35,140 +37,21 @@ # # Menu.find_by(name: 'home').buttons.first.linked_page # is a ::Page # # @api Model class WCC::Contentful::Model - extend WCC::Contentful::Helpers + include WCC::Contentful::ModelAPI # The Model base class maintains a registry which is best expressed as a # class var. # rubocop:disable Style/ClassVars class << self - include WCC::Contentful::ServiceAccessors - def const_missing(name) + type = WCC::Contentful::Helpers.content_type_from_constant(name) raise WCC::Contentful::ContentTypeNotFoundError, - "Content type '#{content_type_from_constant(name)}' does not exist in the space" + "Content type '#{type}' does not exist in the space" end - end - - @@registry = {} - - def self.store(preview = false) - if preview - if preview_store.nil? - raise ArgumentError, - 'You must include a contentful preview token in your WCC::Contentful.configure block' - end - preview_store - else - super() - end - end - - # Finds an Entry or Asset by ID in the configured contentful space - # and returns an initialized instance of the appropriate model type. - # - # Makes use of the {WCC::Contentful::Services#store configured store} - # to access the Contentful CDN. - def self.find(id, options: nil) - options ||= {} - raw = store(options[:preview]) - .find(id, options.except(*WCC::Contentful::ModelMethods::MODEL_LAYER_CONTEXT_KEYS)) - - new_from_raw(raw, options) if raw.present? - end - - # Creates a new initialized instance of the appropriate model type for the - # given raw value. The raw value must be the same format as returned from one - # of the stores for a given object. - def self.new_from_raw(raw, context = nil) - content_type = content_type_from_raw(raw) - const = resolve_constant(content_type) - const.new(raw, context) - end - - # Accepts a content type ID as a string and returns the Ruby constant - # stored in the registry that represents this content type. - def self.resolve_constant(content_type) - raise ArgumentError, 'content_type cannot be nil' unless content_type - - const = @@registry[content_type] - return const if const - - const_name = constant_from_content_type(content_type).to_s - begin - # The app may have defined a model and we haven't loaded it yet - const = Object.const_missing(const_name) - return const if const && const < WCC::Contentful::Model - rescue NameError => e - raise e unless e.message =~ /uninitialized constant #{const_name}/ - - nil - end - - # Autoloading couldn't find their model - we'll register our own. - const = WCC::Contentful::Model.const_get(constant_from_content_type(content_type)) - register_for_content_type(content_type, klass: const) - end - - # Registers a class constant to be instantiated when resolving an instance - # of the given content type. This automatically happens for the first subclass - # of a generated model type, example: - # - # class MyMenu < WCC::Contentful::Model::Menu - # end - # - # In the above case, instances of MyMenu will be instantiated whenever a 'menu' - # content type is resolved. - # The mapping can be made explicit with the optional parameters. Example: - # - # class MyFoo < WCC::Contentful::Model::Foo - # register_for_content_type 'bar' # MyFoo is assumed - # end - # - # # in initializers/wcc_contentful.rb - # WCC::Contentful::Model.register_for_content_type('bar', klass: MyFoo) - def self.register_for_content_type(content_type = nil, klass: nil) - klass ||= self - raise ArgumentError, "#{klass} must be a class constant!" unless klass.respond_to?(:new) - - content_type ||= content_type_from_constant(klass) - - @@registry[content_type] = klass - end - - # Returns the current registry of content type names to constants. - def self.registry - return {} unless @@registry - - @@registry.dup.freeze - end - - def self.reload! - registry = self.registry - registry.each do |(content_type, klass)| - const_name = klass.name - begin - const = Object.const_missing(const_name) - register_for_content_type(content_type, klass: const) if const - rescue NameError => e - msg = "Error when reloading constant #{const_name} - #{e}" - if defined?(Rails) && Rails.logger - Rails.logger.error msg - else - puts msg - end - end - end - end - - # Checks if a content type has already been registered to a class and returns - # that class. If nil, the generated WCC::Contentful::Model::{content_type} class - # will be resolved for this content type. - def self.registered?(content_type) - @@registry[content_type] end end # rubocop:enable Style/ClassVars