-
-
Notifications
You must be signed in to change notification settings - Fork 317
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add has_many ingredients relation to element
- Loading branch information
Showing
3 changed files
with
137 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# frozen_string_literal: true | ||
|
||
module Alchemy | ||
class Element < BaseRecord | ||
# Methods concerning ingredients for elements | ||
# | ||
module ElementIngredients | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
attr_accessor :autogenerate_ingredients | ||
|
||
has_many :ingredients, | ||
class_name: "Alchemy::Ingredient", | ||
inverse_of: :element, | ||
dependent: :destroy | ||
|
||
after_create :create_ingredients, | ||
unless: -> { autogenerate_ingredients == false } | ||
end | ||
|
||
# Find first ingredient from element by given name. | ||
def ingredient_by_name(name) | ||
ingredients_by_name(name).first | ||
end | ||
|
||
# Find first ingredient from element by given type. | ||
def ingredient_by_type(type) | ||
ingredients_by_type(type).first | ||
end | ||
|
||
# All ingredients from element by given name. | ||
def ingredients_by_name(name) | ||
ingredients.select { |ingredient| ingredient.name == name.to_s } | ||
end | ||
|
||
# All ingredients from element by given type. | ||
def ingredients_by_type(type) | ||
ingredients.select do |ingredient| | ||
ingredient.type == Ingredient.normalize_type(type) | ||
end | ||
end | ||
|
||
# Updates all related ingredients by calling +update+ on each of them. | ||
# | ||
# @param ingredients_attributes [Hash] | ||
# Hash of ingredients attributes. | ||
# The keys has to be the #id of the ingredient to update. | ||
# The values a Hash of attribute names and values | ||
# | ||
# @return [Boolean] | ||
# True if +errors+ are blank or +ingredients_attributes+ hash is nil | ||
# | ||
# == Example | ||
# | ||
# @element.update_ingredients( | ||
# "1" => {ingredient: "Title"}, | ||
# "2" => {link: "https://google.com"} | ||
# ) | ||
# | ||
def update_ingredients(ingredients_attributes) | ||
return true if ingredients_attributes.nil? | ||
|
||
ingredients.each do |ingredient| | ||
ingredient_hash = ingredients_attributes[ingredient.id.to_s] || next | ||
ingredient.update(ingredient_hash) || errors.add(:ingredients, :validation_failed) | ||
end | ||
|
||
errors.empty? | ||
end | ||
|
||
# Copy current ingredient's ingredients to given target element | ||
def copy_ingredients_to(element) | ||
ingredients.map do |ingredient| | ||
Ingredient.copy(ingredient, element_id: element.id) | ||
end | ||
end | ||
|
||
# Returns all element ingredient definitions from the +elements.yml+ file | ||
def ingredient_definitions | ||
definition.fetch(:ingredients, []) | ||
end | ||
|
||
# Returns the definition for given ingredient role | ||
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["name"] == role.to_s } | ||
end | ||
end | ||
|
||
# Returns an array of all Richtext ingredients ids from elements | ||
# | ||
# This is used to re-initialize the TinyMCE editor in the element editor. | ||
# | ||
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 | ||
|
||
# Has any of the ingredients validations defined? | ||
def has_validations? | ||
ingredients.any?(&:has_validations?) | ||
end | ||
|
||
# All element ingredients where the validation has failed. | ||
def ingredients_with_errors | ||
ingredients.select(&:validation_failed?) | ||
end | ||
|
||
private | ||
|
||
# Builds ingredients for this element as described in the +elements.yml+ | ||
def build_ingredients | ||
definition.fetch("ingredients", []).map do |attributes| | ||
Ingredient.new(attributes.merge(element: self)) | ||
end | ||
end | ||
|
||
# Creates ingredients for this element as described in the +elements.yml+ | ||
def create_ingredients | ||
build_ingredients.map(&:save) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters