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 description used for finding the content in elements.yml file



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

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

#content_description(element, essence_hash) ⇒ Object

Returns the content description for building a content.

  1. It looks in the element’s contents description

  2. It builds a description 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_description(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_description_from_essence_type(element, essence_hash['essence_type'])
  else
    content_description_from_element(element, essence_hash['name'])
  end
end

#content_description_from_element(element, name) ⇒ Object

Returns the content description hash from element.

It first uses the normal content description described in the elements.yml contents array.

If the content description could not be found it tries to load it from available_contents array.

Parameters:

  • The (Alchemy::Element)

    element instance the content is for

  • The (String)

    name of the content



111
112
113
114
# File 'app/models/alchemy/content/factory.rb', line 111

def content_description_from_element(element, name)
  element.content_description_for(name) ||
    element.available_content_description_for(name)
end

#content_description_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_description_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 = self.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 description 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

#descriptionsObject

Returns all content descriptions from elements.yml



118
119
120
# File 'app/models/alchemy/content/factory.rb', line 118

def descriptions
  Element.descriptions.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



130
131
132
133
134
135
# File 'app/models/alchemy/content/factory.rb', line 130

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

  "Alchemy::#{essence_type}"
end