filtros en los artículos relacionados y PostRelation#where

This commit is contained in:
f 2020-07-02 10:59:58 -03:00
parent 1fa549d3a1
commit 9de23a1506
3 changed files with 40 additions and 9 deletions

View file

@ -1,4 +1,8 @@
# frozen_string_literal: true
# Una plantilla agrupa metadatos que va a tener un artículo
Layout = Struct.new(:site, :name, :metadata, keyword_init: true)
Layout = Struct.new(:site, :name, :metadata, keyword_init: true) do
def value
name.to_s
end
end

View file

@ -5,13 +5,18 @@
class MetadataRelatedPosts < MetadataArray
# Genera un Hash de { title | slug => uuid }
def values
@values ||= site.posts(lang: lang).map do |p|
@values ||= posts.map do |p|
{ title(p) => p.uuid.value }
end.inject(:merge)
end
private
# Obtiene todos los posts y opcionalmente los filtra
def posts
@posts ||= site.posts(lang: lang).where(**filter)
end
def title(post)
post.try(:title).try(:value) || post.try(:slug).try(:value)
end
@ -20,4 +25,9 @@ class MetadataRelatedPosts < MetadataArray
def lang
post.try(:lang).try(:value) || I18n.locale
end
# Encuentra el filtro
def filter
layout.metadata.dig(name, 'filter')&.to_h&.symbolize_keys || {}
end
end

View file

@ -69,17 +69,34 @@ class PostRelation < Array
end
end
# Encuentra el primer post por el valor de un atributo
# XXX: Acepta cualquier atributo
# Encuentra el primer post por el valor de los atributos
#
# @param [Hash]
# @return [Post]
def find_by(**args)
attr = args.first.first
find_generic do |p|
p.attribute?(attr) &&
p.public_send(attr).value == args.first.last
find_generic do |post|
args.map do |attr, value|
post.attribute?(attr) &&
post.public_send(attr).value == value
end.all?
end
end
# Encuentra todos los Post que cumplan las condiciones
#
# @param [Hash]
# @return [PostRelation]
def where(**args)
return self if args.empty?
PostRelation[*select do |post|
args.map do |attr, value|
post.attribute?(attr) &&
post.public_send(attr).value == value
end.all?
end]
end
# Intenta guardar todos y devuelve true si pudo
def save_all(validate: true)
map do |post|