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 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 # Encontrar un sitio por su nombre
def find_site def find_site
id = params[:site_id] || params[:id] id = params[:site_id] || params[:id]

View file

@ -17,17 +17,28 @@ class PostsController < ApplicationController
@site = find_site @site = find_site
@category = params.dig(:category) @category = params.dig(:category)
@layout = params.dig(:layout).try(:to_sym) @layout = params.dig(:layout)
@locale = locale @locale = locale
# XXX: Cada vez que cambiamos un Post tocamos el sitio con lo que es # XXX: Cada vez que cambiamos un Post tocamos el sitio con lo que es
# más simple saber si hubo cambios. # más simple saber si hubo cambios.
if @category || @layout || stale?(@site) if @category || @layout || stale?(@site)
# TODO: Aplicar policy_scope
@posts = @site.posts(lang: locale) @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 # Orden descendiente por número y luego por fecha
@posts.sort_by!(:order, :date).reverse! @posts.sort_by!(:order, :date).reverse!
@usuarie = @site.usuarie? current_usuarie
end end
end end

View file

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

View file

@ -1,8 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# Política de acceso a artículos # Política de acceso a artículos
#
# TODO: Implementar Invitadx
class PostPolicy class PostPolicy
attr_reader :post, :usuarie attr_reader :post, :usuarie
@ -54,18 +52,12 @@ class PostPolicy
@scope = scope @scope = scope
end end
# Las usuarias pueden ver todos los posts
#
# Les invitades solo pueden ver sus propios posts
#
# TODO: Arreglar
def resolve 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.select do |post|
[scope.find do |post| post.usuaries.include? usuarie
post.author.value == usuarie.email end
end].flatten.compact
end end
end end
end end

View file

@ -2,4 +2,5 @@
%th= post_label_t(attribute, post: post) %th= post_label_t(attribute, post: post)
%td{ dir: dir, lang: locale } %td{ dir: dir, lang: locale }
- p = metadata.belongs_to - 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) %th= post_label_t(attribute, post: post)
%td %td
%ul{ dir: dir, lang: locale } %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) %li= link_to p.title.value, site_post_path(site, p.id)

View file

@ -3,7 +3,7 @@
@site.name, @site.name,
link_to(t('posts.index'), link_to(t('posts.index'),
site_posts_path(@site)), site_posts_path(@site)),
@category] @category_name]
%main.row %main.row
%aside.menu.col-md-3 %aside.menu.col-md-3
@ -53,15 +53,6 @@
%tbody %tbody
- dir = t("locales.#{@locale}.dir") - dir = t("locales.#{@locale}.dir")
- @posts.each_with_index do |post, i| - @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 TODO: Solo les usuaries cachean porque tenemos que separar
les botones por permisos. les botones por permisos.
@ -88,9 +79,9 @@
- unless post.categories.value.empty? - unless post.categories.value.empty?
%br %br
%small %small
- post.categories.value.each do |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) do = link_to site_posts_path(@site, category: (c.respond_to?(:uuid) ? c.uuid.value : c)) do
%span{ lang: post.lang.value, dir: dir }= c %span{ lang: post.lang.value, dir: dir }= (c.respond_to?(:title) ? c.title.value : c)
%td %td
= post.date.value.strftime('%F') = post.date.value.strftime('%F')