Module: Alchemy::Element::ElementIngredients

Extended by:
ActiveSupport::Concern
Included in:
Alchemy::Element
Defined in:
app/models/alchemy/element/element_ingredients.rb

Overview

Methods concerning ingredients for elements

Instance Method Summary collapse

Instance Method Details

#copy_ingredients_to(element) ⇒ Object

Copy current ingredient’s ingredients to given target element



55
56
57
58
59
# File 'app/models/alchemy/element/element_ingredients.rb', line 55

def copy_ingredients_to(element)
  ingredients.map do |ingredient|
    Ingredient.copy(ingredient, element_id: element.id)
  end
end

#has_validations?Boolean

Has any of the ingredients validations defined?

Returns:

  • (Boolean)


90
91
92
# File 'app/models/alchemy/element/element_ingredients.rb', line 90

def has_validations?
  ingredients.any?(&:has_validations?)
end

#has_value_for?(role) ⇒ Boolean

True if the element has a ingredient for given name that has a non blank value.

Returns:

  • (Boolean)


101
102
103
# File 'app/models/alchemy/element/element_ingredients.rb', line 101

def has_value_for?(role)
  value_for(role).present?
end

#ingredient_by_role(role) ⇒ Object

Find first ingredient from element by given role.



31
32
33
# File 'app/models/alchemy/element/element_ingredients.rb', line 31

def ingredient_by_role(role)
  ingredients.detect { |ingredient| ingredient.role == role.to_s }
end

#ingredient_by_type(type) ⇒ Object

Find first ingredient from element by given type.



36
37
38
# File 'app/models/alchemy/element/element_ingredients.rb', line 36

def ingredient_by_type(type)
  ingredients_by_type(type).first
end

#ingredient_definition_for(role) ⇒ Object

Returns the definition for given ingredient role



67
68
69
70
71
72
73
74
# File 'app/models/alchemy/element/element_ingredients.rb', line 67

def ingredient_definition_for(role)
  if ingredient_definitions.blank?
    log_warning "Element #{name} is missing the ingredient definition for #{role}"
    nil
  else
    ingredient_definitions.find { |d| d[:role] == role.to_s }
  end
end

#ingredient_definitionsObject

Returns all element ingredient definitions from the elements.yml file



62
63
64
# File 'app/models/alchemy/element/element_ingredients.rb', line 62

def ingredient_definitions
  definition.fetch(:ingredients, [])
end

#ingredient_error_messagesObject

Ingredient validation error messages

Error messages are translated via I18n

Inside your translation file add translations like:

alchemy:
  ingredient_validations:
    name_of_the_element:
      role_of_the_ingredient:
        validation_error_type: Error Message

NOTE: validation_error_type has to be one of:

* blank
* taken
* invalid

Example:

de:
  alchemy:
    ingredient_validations:
      contactform:
        email:
          invalid: 'Die Email hat nicht das richtige Format'

Error message translation fallbacks

In order to not translate every single ingredient for every element you can provide default error messages per content name:

Example

en:
  alchemy:
    ingredient_validations:
      fields:
        email:
          invalid: E-Mail has wrong format
          blank: E-Mail can't be blank

And even further you can provide general field agnostic error messages:

Example

en:
  alchemy:
    ingredient_validations:
      errors:
        invalid: %{field} has wrong format
        blank: %{field} can't be blank


159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'app/models/alchemy/element/element_ingredients.rb', line 159

def ingredient_error_messages
  messages = []
  ingredients_with_errors.map { |i| [i.role, i.errors.details] }.each do |role, error_details|
    error_details[:value].each do |error_detail|
      error = error_detail[:error]
      messages << Alchemy.t(
        "#{name}.#{role}.#{error}",
        scope: "ingredient_validations",
        default: [
          "fields.#{role}.#{error}".to_sym,
          "errors.#{error}".to_sym,
        ],
        field: Alchemy::Ingredient.translated_label_for(role, name),
      )
    end
  end
  messages
end

#ingredients_by_role(role) ⇒ Object

All ingredients from element by given role.



41
42
43
44
45
# File 'app/models/alchemy/element/element_ingredients.rb', line 41

def ingredients_by_role(role)
  ingredients.select do |ingredient|
    ingredient.role == Ingredient.normalize_type(role)
  end
end

#ingredients_by_type(type) ⇒ Object

All ingredients from element by given type.



48
49
50
51
52
# File 'app/models/alchemy/element/element_ingredients.rb', line 48

def ingredients_by_type(type)
  ingredients.select do |ingredient|
    ingredient.type == Ingredient.normalize_type(type)
  end
end

#ingredients_with_errorsObject

All element ingredients where the validation has failed.



95
96
97
# File 'app/models/alchemy/element/element_ingredients.rb', line 95

def ingredients_with_errors
  ingredients.select { |i| i.errors.any? }
end

#richtext_ingredients_idsObject

Returns an array of all Richtext ingredients ids from elements

This is used to re-initialize the TinyMCE editor in the element editor.



80
81
82
83
84
85
86
87
# File 'app/models/alchemy/element/element_ingredients.rb', line 80

def richtext_ingredients_ids
  ids = ingredients.select(&:has_tinymce?).collect(&:id)
  expanded_nested_elements = nested_elements.expanded
  if expanded_nested_elements.present?
    ids += expanded_nested_elements.collect(&:richtext_ingredients_ids)
  end
  ids.flatten
end

#value_for(role) ⇒ Object

The value of an ingredient of the element by role



26
27
28
# File 'app/models/alchemy/element/element_ingredients.rb', line 26

def value_for(role)
  ingredient_by_role(role)&.value
end