From 4d728633c9157043ebd7580807d1a5fe990b91bf Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Wed, 9 Mar 2022 21:54:25 +0100 Subject: [PATCH] Fix setting default value of ingredients Somehow before_validation is not called ever during creating an element and its ingredients. Using after_initialize fixes this. Closes #2189 --- app/models/alchemy/ingredient.rb | 7 ++++++- .../test_support/shared_ingredient_examples.rb | 6 ++++-- spec/dummy/config/alchemy/elements.yml | 1 + spec/models/alchemy/element_ingredients_spec.rb | 4 +++- .../alchemy/ingredients/boolean_editor_spec.rb | 17 +++++------------ 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/app/models/alchemy/ingredient.rb b/app/models/alchemy/ingredient.rb index 27c01be287..d366c84c99 100644 --- a/app/models/alchemy/ingredient.rb +++ b/app/models/alchemy/ingredient.rb @@ -11,7 +11,8 @@ class DefinitionError < StandardError; end belongs_to :element, touch: true, class_name: "Alchemy::Element", inverse_of: :ingredients belongs_to :related_object, polymorphic: true, optional: true - before_validation(on: :create) { self.value ||= default_value } + after_initialize :set_default_value, + if: -> { definition.key?(:default) && value.nil? } validates :type, presence: true validates :role, presence: true @@ -161,6 +162,10 @@ def hint_translation_attribute role end + def set_default_value + self.value = default_value + end + # Returns the default value from ingredient definition # # If the value is a symbol it gets passed through i18n diff --git a/lib/alchemy/test_support/shared_ingredient_examples.rb b/lib/alchemy/test_support/shared_ingredient_examples.rb index cb271d7bbd..8f7e548226 100644 --- a/lib/alchemy/test_support/shared_ingredient_examples.rb +++ b/lib/alchemy/test_support/shared_ingredient_examples.rb @@ -28,7 +28,7 @@ context "with element" do before do - expect(element).to receive(:ingredient_definition_for) do + expect(element).to receive(:ingredient_definition_for).at_least(:once) do { settings: { linkable: true, @@ -63,7 +63,9 @@ end before do - expect(element).to receive(:ingredient_definition_for) { definition } + expect(element).to receive(:ingredient_definition_for).at_least(:once) do + definition + end end it "returns ingredient definition" do diff --git a/spec/dummy/config/alchemy/elements.yml b/spec/dummy/config/alchemy/elements.yml index e7184b126d..b219136ea7 100644 --- a/spec/dummy/config/alchemy/elements.yml +++ b/spec/dummy/config/alchemy/elements.yml @@ -160,6 +160,7 @@ - role: boolean type: Boolean hint: true + default: true - role: datetime type: Datetime hint: true diff --git a/spec/models/alchemy/element_ingredients_spec.rb b/spec/models/alchemy/element_ingredients_spec.rb index 5832b3d107..b4cb940092 100644 --- a/spec/models/alchemy/element_ingredients_spec.rb +++ b/spec/models/alchemy/element_ingredients_spec.rb @@ -97,7 +97,9 @@ end describe "#has_value_for?" do - let!(:element) { create(:alchemy_element, :with_ingredients) } + let!(:element) do + create(:alchemy_element, :with_ingredients, name: "all_you_can_eat_ingredients") + end context "with role existing" do let(:ingredient) { element.ingredient_by_role(:headline) } diff --git a/spec/views/alchemy/ingredients/boolean_editor_spec.rb b/spec/views/alchemy/ingredients/boolean_editor_spec.rb index fcf60831e9..a7fbff434b 100644 --- a/spec/views/alchemy/ingredients/boolean_editor_spec.rb +++ b/spec/views/alchemy/ingredients/boolean_editor_spec.rb @@ -28,21 +28,14 @@ end context "with default value given in ingredient settings" do - let(:element) { create(:alchemy_element, name: "all_you_can_eat_ingredients") } - - let(:ingredient) do - allow_any_instance_of(Alchemy::Ingredients::Boolean).to receive(:definition) do - { - role: "boolean", - type: "Boolean", - default: true, - }.with_indifferent_access - end - Alchemy::Ingredients::Boolean.create!(role: "boolean", element: element) + let(:element) do + create(:alchemy_element, :with_ingredients, name: "all_you_can_eat_ingredients") end it "checks the checkbox" do - is_expected.to have_selector('input[type="checkbox"][checked="checked"]') + within ".ingredient-editor boolean" do + is_expected.to have_selector('input[type="checkbox"][checked="checked"]') + end end end end