72 lines
1.5 KiB
Ruby
72 lines
1.5 KiB
Ruby
|
# 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
|
||
|
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
|