# 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 # Obtiene el valor desde el documento. # # @return [String] def document_value document.data[name.to_s] 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. def save super # Si no hay relación inversa, no hacer nada más return true unless changed? return true unless inverse? # Si estamos cambiando la relación, tenemos que eliminar la relación # anterior if belonged_to.present? belonged_to[inverse].value = belonged_to[inverse].value.reject do |rej| rej == post.uuid.value end end # No duplicar las relaciones belongs_to[inverse].value = (belongs_to[inverse].value.dup << 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 @inverse ||= layout.metadata.dig(name, 'inverse')&.to_sym end # El Post relacionado con este artículo def belongs_to posts.find(value, uuid: true) if value.present? end # El artículo relacionado anterior def belonged_to posts.find(value_was, uuid: true) if value_was.present? end def related_posts? true end def related_methods @related_methods ||= %i[belongs_to belonged_to].freeze end def indexable_values belongs_to&.title&.value end private def post_exists? return true if sanitize(value).blank? sanitize(value).present? && belongs_to.present? end def sanitize(uuid) uuid.to_s.gsub(/[^a-f0-9\-]/i, '') end end