mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 15:26:22 +00:00
90 lines
2.4 KiB
Ruby
90 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Establece una relación de muchos a muchos artículos. Cada campo es un
|
|
# Array de UUID que se mantienen sincronizados.
|
|
#
|
|
# Por ejemplo:
|
|
#
|
|
# Un libro puede tener muches autores y une autore muchos libros. La
|
|
# relación has_many tiene que traer todes les autores relacionades con
|
|
# el libro actual. La relación belongs_to tiene que traer todes les
|
|
# autores que tienen este libro. La relación es bidireccional, no hay
|
|
# diferencia entre has_many y belongs_to.
|
|
class MetadataHasAndBelongsToMany < MetadataBelongsTo
|
|
def default_value
|
|
[]
|
|
end
|
|
|
|
# Posts a los que pertenece. Memoizamos por value para obtener
|
|
# siempre la última relación.
|
|
#
|
|
# Buscamos todos los Post contenidos en el valor actual. No
|
|
# garantizamos el orden.
|
|
#
|
|
# @return [PostRelation] Posts
|
|
def belongs_to
|
|
@belongs_to ||= {}
|
|
@belongs_to[value.hash.to_s] ||= posts.where(uuid: value)
|
|
end
|
|
|
|
# Devuelve la lista de Posts relacionados con este buscándolos en la
|
|
# relación inversa. #save debería mantenerlos sincronizados.
|
|
#
|
|
# @return [PostRelation]
|
|
def has_many
|
|
@has_many ||= {}
|
|
@has_many[value.hash.to_s] ||= posts.where(inverse.to_sym => post.uuid.value)
|
|
end
|
|
alias had_many has_many
|
|
|
|
# Posts a los que pertenecía
|
|
#
|
|
# @return [PostRelation] Posts
|
|
def belonged_to
|
|
@belonged_to ||= posts.where(uuid: document.data.fetch(name.to_s, []))
|
|
end
|
|
|
|
# Mantiene la relación inversa si existe.
|
|
#
|
|
# La relación belongs_to se mantiene actualizada en la modificación
|
|
# actual. Lo que buscamos es mantener sincronizada esa relación.
|
|
#
|
|
# Buscamos en belongs_to la relación local, si se eliminó hay que
|
|
# quitarla de la relación remota, sino hay que agregarla.
|
|
def save
|
|
return true unless changed?
|
|
|
|
self[:value] = sanitize value
|
|
|
|
return true unless inverse? && !included?
|
|
|
|
(belonged_to - belongs_to).each do |p|
|
|
p[inverse].value.delete post.uuid.value
|
|
end
|
|
|
|
(belongs_to - belonged_to).each do |p|
|
|
p[inverse].value << post.uuid.value
|
|
end
|
|
|
|
true
|
|
end
|
|
|
|
def sanitize(sanitizable)
|
|
sanitizable.map do |v|
|
|
super v
|
|
end
|
|
end
|
|
|
|
def post_exists?
|
|
return true if empty? && can_be_empty?
|
|
|
|
!belongs_to.empty?
|
|
end
|
|
|
|
# Todos los artículos relacionados incluyen a este?
|
|
def included?
|
|
belongs_to.map do |p|
|
|
p[inverse].value.include? post.uuid.value
|
|
end.all?
|
|
end
|
|
end
|