revisión de habtm
This commit is contained in:
parent
bbdbfc4ee1
commit
c5cd07a82e
6 changed files with 38 additions and 60 deletions
|
@ -23,7 +23,7 @@ class MetadataBelongsTo < MetadataRelatedPosts
|
||||||
def validate
|
def validate
|
||||||
super
|
super
|
||||||
|
|
||||||
errors << I18n.t('metadata.belongs_to.missing_post') if value.present? && !post_exists?
|
errors << I18n.t('metadata.belongs_to.missing_post') unless post_exists?
|
||||||
|
|
||||||
errors.empty?
|
errors.empty?
|
||||||
end
|
end
|
||||||
|
@ -59,7 +59,7 @@ class MetadataBelongsTo < MetadataRelatedPosts
|
||||||
|
|
||||||
# El campo que es la relación inversa de este
|
# El campo que es la relación inversa de este
|
||||||
def inverse
|
def inverse
|
||||||
layout.metadata.dig name, 'inverse'
|
@inverse ||= layout.metadata.dig(name, 'inverse')&.to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
# El Post relacionado con este artículo
|
# El Post relacionado con este artículo
|
||||||
|
@ -90,7 +90,7 @@ class MetadataBelongsTo < MetadataRelatedPosts
|
||||||
private
|
private
|
||||||
|
|
||||||
def post_exists?
|
def post_exists?
|
||||||
posts.find(value, uuid: true).present?
|
value.present? && belongs_to.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def sanitize(uuid)
|
def sanitize(uuid)
|
||||||
|
|
|
@ -10,40 +10,7 @@
|
||||||
# el libro actual. La relación belongs_to tiene que traer todes les
|
# 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
|
# autores que tienen este libro. La relación es bidireccional, no hay
|
||||||
# diferencia entre has_many y belongs_to.
|
# diferencia entre has_many y belongs_to.
|
||||||
class MetadataHasAndBelongsToMany < MetadataBelongsTo
|
class MetadataHasAndBelongsToMany < MetadataHasMany
|
||||||
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.
|
# Mantiene la relación inversa si existe.
|
||||||
#
|
#
|
||||||
# La relación belongs_to se mantiene actualizada en la modificación
|
# La relación belongs_to se mantiene actualizada en la modificación
|
||||||
|
@ -52,39 +19,33 @@ class MetadataHasAndBelongsToMany < MetadataBelongsTo
|
||||||
# Buscamos en belongs_to la relación local, si se eliminó hay que
|
# Buscamos en belongs_to la relación local, si se eliminó hay que
|
||||||
# quitarla de la relación remota, sino hay que agregarla.
|
# quitarla de la relación remota, sino hay que agregarla.
|
||||||
def save
|
def save
|
||||||
return true unless changed?
|
# XXX: No usamos super
|
||||||
|
|
||||||
self[:value] = sanitize value
|
self[:value] = sanitize value
|
||||||
|
|
||||||
return true unless inverse? && !included?
|
return true unless changed?
|
||||||
|
return true unless inverse?
|
||||||
|
|
||||||
(belonged_to - belongs_to).each do |p|
|
(had_many - has_many).each do |remove|
|
||||||
p[inverse].value.delete post.uuid.value
|
remove[inverse]&.value&.delete post.uuid.value
|
||||||
end
|
end
|
||||||
|
|
||||||
(belongs_to - belonged_to).each do |p|
|
(has_many - had_many).each do |add|
|
||||||
p[inverse].value << post.uuid.value
|
next unless add[inverse]
|
||||||
|
next if add[inverse].value.include? post.uuid.value
|
||||||
|
|
||||||
|
add[inverse].value << post.uuid.value
|
||||||
end
|
end
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def sanitize(sanitizable)
|
private
|
||||||
sanitizable.map do |v|
|
|
||||||
super v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def post_exists?
|
# Igual que en MetadataRelatedPosts
|
||||||
return true if empty? && can_be_empty?
|
# TODO: Mover a un módulo
|
||||||
|
def sanitize(uuid)
|
||||||
!belongs_to.empty?
|
super(uuid.map do |u|
|
||||||
end
|
u.to_s.gsub(/[^a-f0-9\-]/i, '')
|
||||||
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,14 @@ class MetadataHasMany < MetadataRelatedPosts
|
||||||
super(new_value)
|
super(new_value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate
|
||||||
|
super
|
||||||
|
|
||||||
|
errors << I18n.t('metadata.has_many.missing_posts') unless posts_exist?
|
||||||
|
|
||||||
|
errors.empty?
|
||||||
|
end
|
||||||
|
|
||||||
# Todos los Post relacionados
|
# Todos los Post relacionados
|
||||||
def has_many
|
def has_many
|
||||||
@has_many ||= posts.where(uuid: value)
|
@has_many ||= posts.where(uuid: value)
|
||||||
|
@ -63,4 +71,8 @@ class MetadataHasMany < MetadataRelatedPosts
|
||||||
def related_methods
|
def related_methods
|
||||||
@related_methods ||= %i[has_many had_many].freeze
|
@related_methods ||= %i[has_many had_many].freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def posts_exist?
|
||||||
|
has_many.size == value.size
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
.form-group
|
.form-group
|
||||||
= label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post)
|
= label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post)
|
||||||
|
= hidden_field_tag "#{base}[#{attribute}][]", ''
|
||||||
|
|
||||||
.mapable{ dir: dir, lang: locale,
|
.mapable{ dir: dir, lang: locale,
|
||||||
data: { values: metadata.value.to_json,
|
data: { values: metadata.value.to_json,
|
||||||
|
|
|
@ -48,6 +48,8 @@ en:
|
||||||
end_in_the_past: "Event end can't happen before the start"
|
end_in_the_past: "Event end can't happen before the start"
|
||||||
belongs_to:
|
belongs_to:
|
||||||
missing_post: "Couldn't find the related post"
|
missing_post: "Couldn't find the related post"
|
||||||
|
has_many:
|
||||||
|
missing_posts: "Couldn't find some related posts"
|
||||||
exceptions:
|
exceptions:
|
||||||
post:
|
post:
|
||||||
site_missing: 'Needs an instance of Site'
|
site_missing: 'Needs an instance of Site'
|
||||||
|
|
|
@ -48,6 +48,8 @@ es:
|
||||||
end_in_the_past: 'El fin del evento no puede ser anterior al comienzo'
|
end_in_the_past: 'El fin del evento no puede ser anterior al comienzo'
|
||||||
belongs_to:
|
belongs_to:
|
||||||
missing_post: 'No se pudo encontrar el artículo relacionado'
|
missing_post: 'No se pudo encontrar el artículo relacionado'
|
||||||
|
has_many:
|
||||||
|
missing_posts: 'No se pudieron encontrar algunos artículos relacionados'
|
||||||
exceptions:
|
exceptions:
|
||||||
post:
|
post:
|
||||||
site_missing: 'Necesita una instancia de Site'
|
site_missing: 'Necesita una instancia de Site'
|
||||||
|
|
Loading…
Reference in a new issue