# 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? if belonged_to[inverse].respond_to? :has_one belonged_to[inverse].value = '' else belonged_to[inverse].value = belonged_to[inverse].value.reject do |rej| rej == post.uuid.value end end end # No duplicar las relaciones if belongs_to.present? if belongs_to[inverse].respond_to? :has_one belongs_to[inverse].value = post.uuid.value else belongs_to[inverse].value = (belongs_to[inverse].value.dup << post.uuid.value) unless belongs_to.blank? || included? end end 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 # # @return [Post,nil] def belongs_to posts.find_by(post_id: value)&.post if value.present? end # El artículo relacionado anterior # # @return [Post,nil] def belonged_to posts.find_by(post_id: value_was)&.post 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