# 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') unless 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 return super unless inverse? && !included? # Evitar que se cambie el orden de la relación belonged_to&.dig(inverse)&.value&.delete post.uuid.value if belonged_to != belongs_to belongs_to[inverse].value << post.uuid.value unless belongs_to[inverse].value.include? post.uuid.value 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? && belongs_to.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 anterior artículo relacionado def belonged_to return if document.data[name.to_s].blank? @belonged_to ||= posts.find(document.data[name.to_s], 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? !value.blank? && posts.find(sanitize(value), uuid: true) end end