mejoras en filtros y relaciones de posts y categorías

This commit is contained in:
f 2020-09-25 14:07:54 -03:00
parent 7c518d67de
commit c2a4965fed
7 changed files with 36 additions and 32 deletions

View File

@ -26,6 +26,10 @@ class ApplicationController < ActionController::Base
private
def uuid?(string)
/[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}/ =~ string
end
# Encontrar un sitio por su nombre
def find_site
id = params[:site_id] || params[:id]

View File

@ -17,17 +17,28 @@ class PostsController < ApplicationController
@site = find_site
@category = params.dig(:category)
@layout = params.dig(:layout).try(:to_sym)
@layout = params.dig(:layout)
@locale = locale
# XXX: Cada vez que cambiamos un Post tocamos el sitio con lo que es
# más simple saber si hubo cambios.
if @category || @layout || stale?(@site)
# TODO: Aplicar policy_scope
@posts = @site.posts(lang: locale)
@posts = @posts.where(categories: @category) if @category
@posts = @posts.where(layout: @layout) if @layout
@posts = PostPolicy::Scope.new(current_usuarie, @posts).resolve
@category_name = if uuid?(@category)
@site.posts(lang: locale).find(@category, uuid: true)&.title&.value
else
@category
end
# Filtrar los posts que les invitades no pueden ver
@usuarie = @site.usuarie? current_usuarie
# Orden descendiente por número y luego por fecha
@posts.sort_by!(:order, :date).reverse!
@usuarie = @site.usuarie? current_usuarie
end
end

View File

@ -84,6 +84,8 @@ class PostRelation < Array
# Encuentra todos los Post que cumplan las condiciones
#
# TODO: Implementar caché
#
# @param [Hash] Mapa de atributo => valor. Valor puede ser un Array
# de valores
# @return [PostRelation]
@ -91,7 +93,7 @@ class PostRelation < Array
return self if args.empty?
PostRelation[*select do |post|
args.map do |attr, value|
result = args.map do |attr, value|
next unless post.attribute?(attr)
attribute = post.public_send(attr)
@ -106,7 +108,10 @@ class PostRelation < Array
else attribute.value == value
end
end
end.compact.all?
end.compact
# Un Array vacío devuelve true para all?
!result.empty? && result.all?
end]
end

View File

@ -1,8 +1,6 @@
# frozen_string_literal: true
# Política de acceso a artículos
#
# TODO: Implementar Invitadx
class PostPolicy
attr_reader :post, :usuarie
@ -54,18 +52,12 @@ class PostPolicy
@scope = scope
end
# Las usuarias pueden ver todos los posts
#
# Les invitades solo pueden ver sus propios posts
#
# TODO: Arreglar
def resolve
return scope if scope.try(:first).try(:site).try(:usuarie?, usuarie)
return scope if scope&.first&.site&.usuarie? usuarie
# Asegurarse que al menos devolvemos []
[scope.find do |post|
post.author.value == usuarie.email
end].flatten.compact
scope.select do |post|
post.usuaries.include? usuarie
end
end
end
end

View File

@ -2,4 +2,5 @@
%th= post_label_t(attribute, post: post)
%td{ dir: dir, lang: locale }
- p = metadata.belongs_to
= link_to p.title.value, site_post_path(site, p.id)
- if p
= link_to p.title.value, site_post_path(site, p.id)

View File

@ -2,5 +2,5 @@
%th= post_label_t(attribute, post: post)
%td
%ul{ dir: dir, lang: locale }
- metadata.has_many.each do |p|
- metadata.belongs_to.each do |p|
%li= link_to p.title.value, site_post_path(site, p.id)

View File

@ -3,7 +3,7 @@
@site.name,
link_to(t('posts.index'),
site_posts_path(@site)),
@category]
@category_name]
%main.row
%aside.menu.col-md-3
@ -53,15 +53,6 @@
%tbody
- dir = t("locales.#{@locale}.dir")
- @posts.each_with_index do |post, i|
-#
saltearse el post a menos que esté en la categoría por
la que estamos filtrando
- if @category
- next unless post.attributes.include? :categories
- next unless post.categories.value.include?(@category)
- if @layout
- next unless post.layout.name == @layout
- next unless @usuarie || policy(post).show?
-#
TODO: Solo les usuaries cachean porque tenemos que separar
les botones por permisos.
@ -88,9 +79,9 @@
- unless post.categories.value.empty?
%br
%small
- post.categories.value.each do |c|
= link_to site_posts_path(@site, category: c) do
%span{ lang: post.lang.value, dir: dir }= c
- (post.categories.respond_to?(:belongs_to) ? post.categories.belongs_to : post.categories.value).each do |c|
= link_to site_posts_path(@site, category: (c.respond_to?(:uuid) ? c.uuid.value : c)) do
%span{ lang: post.lang.value, dir: dir }= (c.respond_to?(:title) ? c.title.value : c)
%td
= post.date.value.strftime('%F')