class WCC::Contentful::Model

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 classes. A model class represents a content type inside Contentful. For example, the “page” content type is represented by a class named WCC::Contentful::Model::Page

This WCC::Contentful::Model::Page class exposes the following API methods:

The returned objects are instances of WCC::Contentful::Model::Page, or whatever constant exists in the registry for the page content type. You can register custom types to be instantiated for each content type. If a Model is subclassed, the subclass is automatically registered. This allows you to put models in your app's `app/models` directory:

class Page < WCC::Contentful::Model::Page; end

and then use the API via those models:

# this returns a ::Page, not a WCC::Contentful::Model::Page
Page.find_by(slug: 'foo')

Furthermore, anytime links are automatically resolved, the registered classes will be used:

Menu.find_by(name: 'home').buttons.first.linked_page # is a ::Page

@api Model

Public Class Methods

const_missing(name) click to toggle source
# File lib/wcc/contentful/model.rb, line 49
def const_missing(name)
  raise WCC::Contentful::ContentTypeNotFoundError,
    "Content type '#{content_type_from_constant(name)}' does not exist in the space"
end
find(id, options: nil) click to toggle source

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.

# File lib/wcc/contentful/model.rb, line 74
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
new_from_raw(raw, context = nil) click to toggle source

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.

# File lib/wcc/contentful/model.rb, line 85
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
register_for_content_type(content_type = nil, klass: nil) click to toggle source

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)
# File lib/wcc/contentful/model.rb, line 132
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
registered?(content_type) click to toggle source

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.

# File lib/wcc/contentful/model.rb, line 169
def self.registered?(content_type)
  @@registry[content_type]
end
registry() click to toggle source

Returns the current registry of content type names to constants.

# File lib/wcc/contentful/model.rb, line 142
def self.registry
  return {} unless @@registry

  @@registry.dup.freeze
end
reload!() click to toggle source
# File lib/wcc/contentful/model.rb, line 148
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
resolve_constant(content_type) click to toggle source

Accepts a content type ID as a string and returns the Ruby constant stored in the registry that represents this content type.

# File lib/wcc/contentful/model.rb, line 93
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
store(preview = false) click to toggle source
Calls superclass method
# File lib/wcc/contentful/model.rb, line 57
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