Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return ingredients value if element asked for ingredient #2170

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions app/helpers/alchemy/elements_block_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,23 @@ def content(name)
# If the element uses +ingredients+ it returns the +value+ of the ingredient record.
#
def ingredient(name)
element.ingredient(name).presence || element.ingredient_by_role(name)&.value
element.ingredient(name)
end

deprecate ingredient: :value, deprecator: Alchemy::Deprecation

# Returns the value of one of the element's ingredients.
#
def value(name)
element.ingredient_by_role(name)&.value
element.value_for(name)
end

# Returns true if the given content or ingredient has been filled by the user.
# Returns true if the given content or ingredient has a value.
#
def has?(name)
element.has_ingredient?(name) || element.has_value_for?(name)
if element.ingredient_definitions.any?
element.has_value_for?(name)
else
element.has_ingredient?(name)
end
end

# Return's the given content's essence.
Expand Down
17 changes: 14 additions & 3 deletions app/models/alchemy/element/element_essences.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,28 @@ class Element < BaseRecord
module ElementEssences
# Returns the contents essence value (aka. ingredient) for passed content name.
def ingredient(name)
content = content_by_name(name)
return nil if content.blank?
ing = ingredient_by_role(name)
if ing
Alchemy::Deprecation.warn <<~WARN
Using `element.ingredient` to get the value of an ingredient is deprecated and will change in Alchemy 6.1
If you want to read the value of an elements ingredient please use `element.value_for(:ingredient_role)` instead.
The next version of Alchemy will return a `Alchemy::Ingredient` record instead.
WARN
ing.value
else
content = content_by_name(name)
return nil if content.blank?

content.ingredient
content.ingredient
end
end

# True if the element has a content for given name,
# that has an essence value (aka. ingredient) that is not blank.
def has_ingredient?(name)
ingredient(name).present?
end
deprecate has_ingredient?: :has_value_for?, deprecator: Alchemy::Deprecation

# Returns all essence errors in the format of:
#
Expand Down
7 changes: 6 additions & 1 deletion app/models/alchemy/element/element_ingredients.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ module ElementIngredients
validates_associated :ingredients, on: :update
end

# The value of an ingredient of the element by role
def value_for(role)
ingredient_by_role(role)&.value
end

# Find first ingredient from element by given role.
def ingredient_by_role(role)
ingredients.detect { |ingredient| ingredient.role == role.to_s }
Expand Down Expand Up @@ -87,7 +92,7 @@ def ingredients_with_errors
# True if the element has a ingredient for given name
# that has a non blank value.
def has_value_for?(role)
ingredient_by_role(role)&.value.present?
value_for(role).present?
end

# Ingredient validation error messages
Expand Down
16 changes: 14 additions & 2 deletions spec/helpers/alchemy/elements_block_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,24 @@ module Alchemy
let(:ingredient) { element.ingredients.first }

it "should return the ingredients value" do
expect(ingredient).to receive(:value).and_call_original
subject.ingredient(:headline)
Alchemy::Deprecation.silenced do
expect(ingredient).to receive(:value).and_call_original
subject.ingredient(:headline)
end
end
end
end

describe "#value" do
let(:element) { create(:alchemy_element, :with_ingredients) }
let(:ingredient) { element.ingredients.first }

it "should return the ingredients value" do
expect(element).to receive(:value_for).and_call_original
subject.value(:headline)
end
end

describe "#has?" do
context "with element having contents" do
it "should delegate to the element's #has_ingredient? method" do
Expand Down
30 changes: 30 additions & 0 deletions spec/models/alchemy/element_ingredients_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,36 @@
end
end

describe "#value_for" do
let!(:element) { create(:alchemy_element, :with_ingredients) }

context "with role existing" do
let(:ingredient) { element.ingredients.first }

context "with blank value" do
before do
expect(ingredient).to receive(:value) { nil }
end

it { expect(element.value_for(:headline)).to be_nil }
end

context "with value present" do
before do
expect(ingredient).to receive(:value) { "Headline" }
end

it "should return value" do
expect(element.value_for(:headline)).to eq("Headline")
end
end
end

context "role not existing" do
it { expect(element.value_for(:foo)).to be_nil }
end
end

describe "#has_value_for?" do
let!(:element) { create(:alchemy_element, :with_ingredients) }

Expand Down
23 changes: 21 additions & 2 deletions spec/models/alchemy/element_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -721,8 +721,27 @@ module Alchemy
context "retrieving contents, essences and ingredients" do
let(:element) { create(:alchemy_element, :with_contents, name: "news") }

it "should return an ingredient by name" do
expect(element.ingredient("news_headline")).to eq(EssenceText.first.ingredient)
describe "#ingredient" do
context "with contents" do
let(:essence) { element.content_by_name(:news_headline) }

it "returns a contents value by name" do
expect(essence).to receive(:ingredient).and_call_original
element.ingredient("news_headline")
end
end

context "with ingredients" do
let(:element) { create(:alchemy_element, :with_ingredients) }
let(:ingredient) { element.ingredient_by_role(:headline) }

it "returns a ingredients value by name" do
Alchemy::Deprecation.silenced do
expect(ingredient).to receive(:value).and_call_original
element.ingredient("headline")
end
end
end
end

it "should return the content for rss title" do
Expand Down