diff --git a/app/decorators/alchemy/element_editor.rb b/app/decorators/alchemy/element_editor.rb index 0b7512c4a5..ff6e11903b 100644 --- a/app/decorators/alchemy/element_editor.rb +++ b/app/decorators/alchemy/element_editor.rb @@ -8,6 +8,17 @@ def to_partial_path "alchemy/admin/elements/element" end + # Returns content editor instances for defined contents + # + # Creates contents on demand if the content is not yet present on the element + # + # @return Array + def contents + element.definition.fetch(:contents, []).map do |content| + Alchemy::ContentEditor.new(find_or_create_content(content[:name])) + end + end + # CSS classes for the element editor partial. def css_classes [ @@ -78,5 +89,19 @@ def deprecation_notice default: Alchemy.t(:element_deprecated)) end end + + private + + def find_or_create_content(name) + find_content(name) || create_content(name) + end + + def find_content(name) + element.contents.find { |content| content.name == name } + end + + def create_content(name) + Alchemy::Content.create(element: element, name: name) + end end end diff --git a/app/views/alchemy/admin/elements/_element.html.erb b/app/views/alchemy/admin/elements/_element.html.erb index f4d4cad029..c759556c04 100644 --- a/app/views/alchemy/admin/elements/_element.html.erb +++ b/app/views/alchemy/admin/elements/_element.html.erb @@ -25,7 +25,7 @@
- <%= render element.contents.map { |content| Alchemy::ContentEditor.new(content) } %> + <%= render element.contents %>
<% if element.taggable? %> diff --git a/spec/decorators/alchemy/element_editor_spec.rb b/spec/decorators/alchemy/element_editor_spec.rb index e9cfc3e7d5..bca04dc838 100644 --- a/spec/decorators/alchemy/element_editor_spec.rb +++ b/spec/decorators/alchemy/element_editor_spec.rb @@ -12,6 +12,44 @@ end end + describe "#contents" do + let(:element) { create(:alchemy_element, :with_contents, name: "headline") } + + subject(:contents) { element_editor.contents } + + it "returns a ContentEditor instance for each content defined" do + aggregate_failures do + contents.each do |content| + expect(content).to be_an(Alchemy::ContentEditor) + end + end + end + + context "with a content defined but not existing yet" do + before do + expect(element).to receive(:definition).at_least(:once) do + { + name: "headline", + contents: [ + { + name: "headline", + type: "EssenceText", + }, + { + name: "foo", + type: "EssenceText", + }, + ], + }.with_indifferent_access + end + end + + it "creates the missing content" do + expect { subject }.to change { element.contents.count }.by(1) + end + end + end + describe "#to_partial_path" do subject { element_editor.to_partial_path }