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



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

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)


83
84
85
# File 'app/models/alchemy/element/element_ingredients.rb', line 83

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)


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

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



60
61
62
63
64
65
66
67
# File 'app/models/alchemy/element/element_ingredients.rb', line 60

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



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

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 ingredient role:

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


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'app/models/alchemy/element/element_ingredients.rb', line 152

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_type(type) ⇒ Object

All ingredients from element by given type.



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

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.



88
89
90
# File 'app/models/alchemy/element/element_ingredients.rb', line 88

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.



73
74
75
76
77
78
79
80
# File 'app/models/alchemy/element/element_ingredients.rb', line 73

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