diff --git a/app/models/metadata_path.rb b/app/models/metadata_path.rb index 7f386928..5dc25c8b 100644 --- a/app/models/metadata_path.rb +++ b/app/models/metadata_path.rb @@ -8,7 +8,8 @@ class MetadataPath < MetadataTemplate end def value - default_value + @value_was ||= default_value + self[:value] = default_value end alias absolute value alias to_s value diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 35dbf455..521a02a8 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -10,6 +10,17 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, :layout, keyword_init: true) do include ActionText::ContentHelper + attr_reader :value_was + + def value=(new_value) + @value_was = value + self[:value] = new_value + end + + def changed? + !value_was.nil? && value_was != value + end + # El valor por defecto def default_value raise NotImplementedError diff --git a/app/models/post.rb b/app/models/post.rb index 215a8ef0..4a80cab5 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -11,6 +11,7 @@ class Post < OpenStruct # Otros atributos que no vienen en los metadatos PRIVATE_ATTRIBUTES = %i[path slug attributes errors].freeze PUBLIC_ATTRIBUTES = %i[lang date uuid].freeze + ATTR_SUFFIXES = %w[? =].freeze class << self # Obtiene el layout sin leer el Document @@ -117,10 +118,6 @@ class Post < OpenStruct method: mid) end - # Definir los attribute_* - new_attribute_was(name) - new_attribute_changed(name) - # OpenStruct super(mid, *args) @@ -193,7 +190,7 @@ class Post < OpenStruct def save(validate: true) return false if validate && !valid? # Salir si tenemos que cambiar el nombre del archivo y no pudimos - return false if !new? && path_changed? && !update_path! + return false if !new? && path.changed? && !update_path! return false unless save_attributes! return false unless write @@ -225,7 +222,7 @@ class Post < OpenStruct # existe el destino def update_path! !File.exist?(path.absolute) && - FileUtils.mv(path_was, path.absolute) && + FileUtils.mv(path.value_was, path.absolute) && document.path = path.absolute end @@ -299,38 +296,11 @@ class Post < OpenStruct document.data.fetch('usuaries', []) end - def new_attribute_was(method) - attr_was = "#{method}_was".to_sym - return attr_was if singleton_class.method_defined? attr_was - - define_singleton_method(attr_was) do - name = attribute_name(attr_was) - if document.respond_to?(name) - document.send(name) - else - document.data[name.to_s] - end - end - end - - # Pregunta si el atributo cambió - def new_attribute_changed(method) - attr_changed = "#{method}_changed?".to_sym - - return attr_changed if singleton_class.method_defined? attr_changed - - define_singleton_method(attr_changed) do - name = attribute_name(attr_changed) - name_was = (name.to_s + '_was').to_sym - - (send(name).try(:value) || send(name)) != send(name_was) - end - end - # Obtiene el nombre del atributo a partir del nombre del método def attribute_name(attr) # XXX: Los simbolos van al final - %w[_was _changed? ? =].reduce(attr.to_s) do |a, suffix| + @attribute_name_cache ||= {} + @attribute_name_cache[attr] ||= ATTR_SUFFIXES.reduce(attr.to_s) do |a, suffix| a.chomp suffix end.to_sym end diff --git a/test/models/post_test.rb b/test/models/post_test.rb index 0235970f..67dd1a24 100644 --- a/test/models/post_test.rb +++ b/test/models/post_test.rb @@ -98,36 +98,32 @@ class PostTest < ActiveSupport::TestCase test 'attribute_name' do assert_equal :hola, @post.send(:attribute_name, :hola) assert_equal :hola, @post.send(:attribute_name, :hola?) - assert_equal :hola, @post.send(:attribute_name, :hola_was) - assert_equal :hola, @post.send(:attribute_name, :hola_changed?) end test 'se puede cambiar el slug' do @post.title.value = SecureRandom.hex - assert_equal @post.slug_was, @post.slug.value - assert_not @post.slug_changed? + assert_not @post.slug.changed? assert @post.slug.valid? ex_slug = @post.slug.value @post.slug.value = SecureRandom.hex assert_not_equal ex_slug, @post.slug.value - assert_equal ex_slug, @post.slug_was - assert @post.slug_changed? + assert_equal ex_slug, @post.slug.value_was + assert @post.slug.changed? assert @post.slug.valid? end test 'se puede cambiar la fecha' do - assert_equal @post.date_was, @post.date.value - assert_not @post.date_changed? + assert_not @post.date.changed? assert @post.date.valid? ex_date = @post.date.value @post.date.value = 2.days.ago assert_not_equal ex_date, @post.date.value - assert_equal ex_date, @post.date_was - assert @post.date_changed? + assert_equal ex_date, @post.date.value_was + assert @post.date.changed? assert @post.date.valid? end @@ -137,7 +133,7 @@ class PostTest < ActiveSupport::TestCase @post.slug.value = title = SecureRandom.hex @post.date.value = hoy - assert @post.path_changed? + assert @post.path.changed? assert_equal "_es/#{hoy.strftime('%F')}-#{title}.markdown", @post.path.relative @@ -165,7 +161,7 @@ class PostTest < ActiveSupport::TestCase assert_not @post.save assert File.exist?(@post.path.absolute) - assert File.exist?(@post.path_was) + assert File.exist?(@post.path.value_was) end test 'se pueden crear nuevos' do