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