# frozen_string_literal: true # La diferencia con MetadataRelatedPosts es que la relación también # actualiza los Posts remotos. # # Localmente tenemos un Array de UUIDs. Remotamente tenemos una String # apuntando a un Post, que se mantiene actualizado como el actual. class MetadataHasMany < MetadataRelatedPosts # Invalidar la relación anterior def value_was=(new_value) @had_many = nil @has_many = nil super(new_value) end def validate super errors << I18n.t('metadata.has_many.missing_posts') unless posts_exist? errors.empty? end # Todos los Post relacionados def has_many @has_many ||= posts.where(uuid: value) end # La relación anterior def had_many return [] if value_was.blank? @had_many ||= posts.where(uuid: value_was) end def inverse? inverse.present? end # La relación inversa # # @return [Nil,Symbol] def inverse @inverse ||= layout.metadata.dig(name, 'inverse')&.to_sym end # Actualizar las relaciones inversas. Hay que buscar la diferencia # entre had y has_many. def save super return true unless changed? return true unless inverse? (had_many - has_many).each do |remove| remove[inverse]&.value = remove[inverse].default_value end (has_many - had_many).each do |add| add[inverse]&.value = post.uuid.value end true end def related_posts? true end def related_methods @related_methods ||= %i[has_many had_many].freeze end def posts_exist? has_many.size == sanitize(value).size end end