From 42c2e4d9e16bf9d1d808ffbbf9c996164f0873b9 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Tue, 29 Jun 2021 20:36:48 +0200 Subject: [PATCH] Use Rails' store_accessor for ingredients data No need to implement this ourselves, Rails has us backed. Thanks @hmans :tada: --- .../alchemy/admin/ingredients_controller.rb | 2 +- app/models/alchemy/ingredient.rb | 16 ------------ app/models/alchemy/ingredients/audio.rb | 11 ++++---- app/models/alchemy/ingredients/file.rb | 9 +++---- app/models/alchemy/ingredients/headline.rb | 7 +++--- app/models/alchemy/ingredients/link.rb | 9 +++---- app/models/alchemy/ingredients/picture.rb | 25 +++++++++---------- app/models/alchemy/ingredients/richtext.rb | 7 +++--- app/models/alchemy/ingredients/text.rb | 11 ++++---- app/models/alchemy/ingredients/video.rb | 19 +++++++------- .../alchemy/ingredient/templates/model.rb.tt | 5 ++-- spec/models/alchemy/ingredient_spec.rb | 12 --------- 12 files changed, 48 insertions(+), 85 deletions(-) diff --git a/app/controllers/alchemy/admin/ingredients_controller.rb b/app/controllers/alchemy/admin/ingredients_controller.rb index 200582d8ec..e0f2c60a9a 100644 --- a/app/controllers/alchemy/admin/ingredients_controller.rb +++ b/app/controllers/alchemy/admin/ingredients_controller.rb @@ -19,7 +19,7 @@ def update private def ingredient_params - params.require(:ingredient).permit(@ingredient.class.ingredient_attributes) + params.require(:ingredient).permit(@ingredient.class.stored_attributes[:data]) end def load_croppable_resource diff --git a/app/models/alchemy/ingredient.rb b/app/models/alchemy/ingredient.rb index 9e56292251..d4d22c9b9d 100644 --- a/app/models/alchemy/ingredient.rb +++ b/app/models/alchemy/ingredient.rb @@ -59,22 +59,6 @@ def create(attributes = {}) build(attributes).tap(&:save) end - # Defines getters and setter methods for ingredient attributes - def ingredient_attributes=(attributes) - @ingredient_attributes = attributes - attributes.each do |name| - define_method name.to_sym do - data[name] - end - define_method "#{name}=" do |value| - data[name] = value - write_attribute(:data, data) - end - end - end - - attr_reader :ingredient_attributes - # Defines getter and setter method aliases for related object # # @param [String|Symbol] The name of the alias diff --git a/app/models/alchemy/ingredients/audio.rb b/app/models/alchemy/ingredients/audio.rb index 6222d92527..81ae185adb 100644 --- a/app/models/alchemy/ingredients/audio.rb +++ b/app/models/alchemy/ingredients/audio.rb @@ -5,12 +5,11 @@ module Ingredients # A audio attachment # class Audio < Alchemy::Ingredient - self.ingredient_attributes = %i[ - autoplay - controls - loop - muted - ] + store_accessor :data, + :autoplay, + :controls, + :muted, + :loop related_object_alias :attachment, class_name: "Alchemy::Attachment" diff --git a/app/models/alchemy/ingredients/file.rb b/app/models/alchemy/ingredients/file.rb index 455a6b4f1b..726222a69e 100644 --- a/app/models/alchemy/ingredients/file.rb +++ b/app/models/alchemy/ingredients/file.rb @@ -7,11 +7,10 @@ module Ingredients # Attach Alchemy::Attachment into this ingredient # class File < Alchemy::Ingredient - self.ingredient_attributes = %i[ - css_class - link_text - title - ] + store_accessor :data, + :css_class, + :link_text, + :title related_object_alias :attachment, class_name: "Alchemy::Attachment" diff --git a/app/models/alchemy/ingredients/headline.rb b/app/models/alchemy/ingredients/headline.rb index 81af68df3d..0e5e3e6582 100644 --- a/app/models/alchemy/ingredients/headline.rb +++ b/app/models/alchemy/ingredients/headline.rb @@ -5,10 +5,9 @@ module Ingredients # A text headline # class Headline < Alchemy::Ingredient - self.ingredient_attributes = %i[ - level - size - ] + store_accessor :data, + :level, + :size before_create :set_level_and_size diff --git a/app/models/alchemy/ingredients/link.rb b/app/models/alchemy/ingredients/link.rb index dca13eea78..f9ac45fa41 100644 --- a/app/models/alchemy/ingredients/link.rb +++ b/app/models/alchemy/ingredients/link.rb @@ -5,11 +5,10 @@ module Ingredients # A URL # class Link < Alchemy::Ingredient - self.ingredient_attributes = %i[ - link_class_name - link_target - link_title - ] + store_accessor :data, + :link_class_name, + :link_target, + :link_title alias_method :link, :value end diff --git a/app/models/alchemy/ingredients/picture.rb b/app/models/alchemy/ingredients/picture.rb index 13d958d858..9038dd6dba 100644 --- a/app/models/alchemy/ingredients/picture.rb +++ b/app/models/alchemy/ingredients/picture.rb @@ -12,19 +12,18 @@ module Ingredients class Picture < Alchemy::Ingredient include Alchemy::PictureThumbnails - self.ingredient_attributes = %i[ - alt_tag - caption - crop_from - crop_size - css_class - link_class_name - link_target - link_title - link - render_size - title - ] + store_accessor :data, + :alt_tag, + :caption, + :crop_from, + :crop_size, + :css_class, + :link_class_name, + :link_target, + :link_title, + :link, + :render_size, + :title related_object_alias :picture, class_name: "Alchemy::Picture" diff --git a/app/models/alchemy/ingredients/richtext.rb b/app/models/alchemy/ingredients/richtext.rb index 9d3db583c1..4ab9690e4d 100644 --- a/app/models/alchemy/ingredients/richtext.rb +++ b/app/models/alchemy/ingredients/richtext.rb @@ -5,10 +5,9 @@ module Ingredients # A blob of richtext # class Richtext < Alchemy::Ingredient - self.ingredient_attributes = %i[ - stripped_body - sanitized_body - ] + store_accessor :data, + :stripped_body, + :sanitized_body before_save :strip_content before_save :sanitize_content diff --git a/app/models/alchemy/ingredients/text.rb b/app/models/alchemy/ingredients/text.rb index 2f0e1ce7d0..af2c3c445c 100644 --- a/app/models/alchemy/ingredients/text.rb +++ b/app/models/alchemy/ingredients/text.rb @@ -7,12 +7,11 @@ module Ingredients # Optionally it can have a link # class Text < Alchemy::Ingredient - self.ingredient_attributes = %i[ - link - link_target - link_title - link_class_name - ] + store_accessor :data, + :link, + :link_target, + :link_title, + :link_class_name end end end diff --git a/app/models/alchemy/ingredients/video.rb b/app/models/alchemy/ingredients/video.rb index 6c248a6c2e..39e9c6a526 100644 --- a/app/models/alchemy/ingredients/video.rb +++ b/app/models/alchemy/ingredients/video.rb @@ -5,16 +5,15 @@ module Ingredients # A video attachment # class Video < Alchemy::Ingredient - self.ingredient_attributes = %i[ - allow_fullscreen - autoplay - controls - height - loop - muted - preload - width - ] + store_accessor :data, + :allow_fullscreen, + :autoplay, + :controls, + :height, + :loop, + :muted, + :preload, + :width related_object_alias :attachment, class_name: "Alchemy::Attachment" diff --git a/lib/generators/alchemy/ingredient/templates/model.rb.tt b/lib/generators/alchemy/ingredient/templates/model.rb.tt index 0cbd60d0c5..fda21a74ec 100644 --- a/lib/generators/alchemy/ingredient/templates/model.rb.tt +++ b/lib/generators/alchemy/ingredient/templates/model.rb.tt @@ -3,9 +3,8 @@ module Alchemy module Ingredients class <%= @class_name %> < Alchemy::Ingredient - # Set additional attributes that get stored in the data JSON column - # Alchemy will create attribute accessors for each of it. - # self.ingredient_attributes = %i[] + # Set additional attributes that get stored in the `data` JSON column + # store_accessor :data, :some, :attribute # Set a related_object alias for convenience # related_object_alias :some_association_name, class_name: "Some::Klass" diff --git a/spec/models/alchemy/ingredient_spec.rb b/spec/models/alchemy/ingredient_spec.rb index 93e7b2aafd..f0245c6507 100644 --- a/spec/models/alchemy/ingredient_spec.rb +++ b/spec/models/alchemy/ingredient_spec.rb @@ -179,18 +179,6 @@ end end - describe "ingredient_attributes=" do - let(:element) { create(:alchemy_element, :with_ingredients, name: "all_you_can_eat_ingredients") } - let(:ingredient) { element.ingredients.first } - - it "persists the value in the data column" do - ingredient.value = "Welcome" - ingredient.level = "2" - ingredient.save! - expect(ingredient.reload.data[:level]).to eq("2") - end - end - describe "#partial_name" do let(:ingredient) { Alchemy::Ingredients::Richtext.build(role: "text", element: element) }