sutty/app/models/metadata_has_many.rb

74 lines
1.6 KiB
Ruby
Raw Normal View History

2020-07-22 23:35:43 +00:00
# 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?
2020-07-22 23:35:43 +00:00
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