Module: Alchemy::Content::Factory::ClassMethods

Defined in:
app/models/alchemy/content/factory.rb

Constant Summary collapse

SKIPPED_ATTRIBUTES_ON_COPY =
%w(position created_at updated_at creator_id updater_id id)

Instance Method Summary collapse

Instance Method Details

#build(element, essence_hash) ⇒ Object

Builds a new content as descriped in the elements.yml file.

Parameters:

  • The (Alchemy::Element)

    element the content is for

  • The (Hash)

    content definition used for finding the content in elements.yml file



17
18
19
20
21
22
23
24
# File 'app/models/alchemy/content/factory.rb', line 17

def build(element, essence_hash)
  definition = content_definition(element, essence_hash)
  if definition.blank?
    raise ContentDefinitionError, "No definition found in elements.yml for #{essence_hash.inspect} and #{element.inspect}"
  else
    new(name: definition['name'], element_id: element.id)
  end
end

#content_definition(element, essence_hash) ⇒ Object

Returns the content definition for building a content.

  1. It looks in the element’s contents definition

  2. It builds a definition hash from essence type, if the the name key is not present



65
66
67
68
69
70
71
72
73
# File 'app/models/alchemy/content/factory.rb', line 65

def content_definition(element, essence_hash)
  essence_hash.stringify_keys!
  # No name given. We build the content from essence type.
  if essence_hash['name'].blank? && essence_hash['essence_type'].present?
    content_definition_from_essence_type(element, essence_hash['essence_type'])
  else
    element.content_definition_for(essence_hash['name'])
  end
end

#content_definition_from_essence_type(element, essence_type) ⇒ Object

Returns a hash for building a content from essence type.

Parameters:

  • The (Alchemy::Element)

    element the content is for.

  • The (String)

    essence type the content is from



82
83
84
85
86
87
# File 'app/models/alchemy/content/factory.rb', line 82

def content_definition_from_essence_type(element, essence_type)
  {
    'type' => essence_type,
    'name' => content_name_from_element_and_essence_type(element, essence_type)
  }
end

#content_name_from_element_and_essence_type(element, essence_type) ⇒ Object

A name for content from its essence type and amount of same essences in element.

Example:

essence_picture_1


95
96
97
98
# File 'app/models/alchemy/content/factory.rb', line 95

def content_name_from_element_and_essence_type(element, essence_type)
  essences_of_same_type = element.contents.where(essence_type: normalize_essence_type(essence_type))
  "#{essence_type.classify.demodulize.underscore}_#{essences_of_same_type.count + 1}"
end

#copy(source, differences = {}) ⇒ Object

Makes a copy of source and also copies the associated essence.

You can pass a differences hash to update the attributes of the copy.

Example

@copy = Alchemy::Content.copy(@content, {:element_id => 3})
@copy.element_id # => 3


50
51
52
53
54
55
56
57
58
# File 'app/models/alchemy/content/factory.rb', line 50

def copy(source, differences = {})
  attributes = source.attributes.except(*SKIPPED_ATTRIBUTES_ON_COPY).merge(differences.stringify_keys)
  content = create!(attributes)
  new_essence = content.essence.class.new(content.essence.attributes.except(*SKIPPED_ATTRIBUTES_ON_COPY))
  new_essence.save!
  raise "Essence not cloned" if new_essence.id == content.essence_id
  content.update_attributes(essence_id: new_essence.id)
  content
end

#create_from_scratch(element, essence_hash) ⇒ Alchemy::Content

Creates a new content from elements definition in the elements.yml file.

  1. It builds the content

  2. It creates the essence record (content object gets saved)

Returns:



33
34
35
36
37
38
39
# File 'app/models/alchemy/content/factory.rb', line 33

def create_from_scratch(element, essence_hash)
  essence_hash.stringify_keys!
  if content = build(element, essence_hash)
    content.create_essence!(essence_hash['essence_type'])
  end
  content
end

#definitionsObject

Returns all content definitions from elements.yml



102
103
104
# File 'app/models/alchemy/content/factory.rb', line 102

def definitions
  Element.definitions.collect { |e| e['contents'] }.flatten.compact
end

#normalize_essence_type(essence_type) ⇒ Object

Returns a normalized Essence type

Adds Alchemy module name in front of given essence type unless there is a Class with the specified name that is an essence.

Parameters:

  • the (String)

    essence type to normalize



114
115
116
117
118
119
# File 'app/models/alchemy/content/factory.rb', line 114

def normalize_essence_type(essence_type)
  essence_type = essence_type.classify
  return essence_type if is_an_essence?(essence_type)

  "Alchemy::#{essence_type}"
end