# frozen_string_literal: true # Almacena el UUID de otro Post y actualiza el valor en el Post # relacionado. class MetadataBelongsTo < MetadataRelatedPosts # TODO: Convertir algunos tipos de valores en módulos para poder # implementar varios tipos de campo sin repetir código # # @include MetadataString # # Una string vacía def default_value '' end def validate super errors << I18n.t('metadata.belongs_to.missing_post') if value.present? && !post_exists? errors.empty? end # Guardar y guardar la relación inversa también, eliminando la # relación anterior si existía. # # XXX: Esto es un poco enclenque, porque habría que guardar tres # archivos en lugar de uno solo e indicarle al artículo que tiene uno # o muchos que busque los datos actualizados filtrando. Pero también # nos ahorra recursos en la búsqueda al cachear la información. En # una relación HABTM también vamos a hacer lo mismo. def save # Si no hay relación inversa, no hacer nada más return super unless inverse? # Si estamos cambiando la relación, tenemos que eliminar la relación # anterior belonged_to[inverse].value.delete post.uuid.value if changed? && belonged_to.present? # No duplicar las relaciones belongs_to[inverse].value << post.uuid.value unless belongs_to.blank? || included? true end # El Post actual está incluido en la relación inversa? def included? belongs_to[inverse].value.include?(post.uuid.value) end # Hay una relación inversa y el artículo existe? def inverse? inverse.present? end # El campo que es la relación inversa de este def inverse layout.metadata.dig name, 'inverse' end # El Post relacionado con este artículo # # XXX: Memoizamos usando el valor para tener el valor siempre # actualizado. def belongs_to return if value.blank? @belongs_to ||= {} @belongs_to[value] ||= posts.find(value, uuid: true) end # El artículo relacionado anterior def belonged_to return if value_was.blank? @belonged_to ||= posts.find(value_was, uuid: true) end def related_posts? true end def related_methods @related_methods ||= %i[belongs_to belonged_to].freeze end private def sanitize(uuid) uuid.gsub(/[^a-f0-9\-]/, '') end def post_exists? posts.find(sanitize(value), uuid: true).present? end end