From 9de23a15062d2a7e7df6142c9ee4e84b6f7fea09 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 Jul 2020 10:59:58 -0300 Subject: [PATCH] =?UTF-8?q?filtros=20en=20los=20art=C3=ADculos=20relaciona?= =?UTF-8?q?dos=20y=20PostRelation#where?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/layout.rb | 6 +++++- app/models/metadata_related_posts.rb | 12 ++++++++++- app/models/post_relation.rb | 31 +++++++++++++++++++++------- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/app/models/layout.rb b/app/models/layout.rb index 43892bec..02f1645b 100644 --- a/app/models/layout.rb +++ b/app/models/layout.rb @@ -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 diff --git a/app/models/metadata_related_posts.rb b/app/models/metadata_related_posts.rb index 0ebc8a02..a0c5fba0 100644 --- a/app/models/metadata_related_posts.rb +++ b/app/models/metadata_related_posts.rb @@ -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 diff --git a/app/models/post_relation.rb b/app/models/post_relation.rb index 336c8bd8..efc970b5 100644 --- a/app/models/post_relation.rb +++ b/app/models/post_relation.rb @@ -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|