# 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 # Todos los Post relacionados según la relación remota def has_many_remote @has_many_remote ||= posts.where(inverse => post.uuid.value) end # Todos los Post relacionados def has_many @has_many ||= {} @has_many[value.hash.to_s] ||= posts.where(uuid: value) end # La relación anterior def had_many return [] if document.data[name.to_s].blank? @had_many ||= posts.where(uuid: document.data[name.to_s]) end def inverse? inverse.present? end # La relación inversa # # @return [Nil,Symbol] def 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 return true unless changed? self[:value] = sanitize value 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 private def sanitize(sanitizable) sanitizable.map do |uuid| uuid.gsub(/[^a-f0-9\-]/, '') end end end