5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-07-04 06:25:45 +00:00
panel/app/models/post_relation.rb

146 lines
3.4 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
# La relación de un sitio con sus artículos, esto nos permite generar
# artículos como si estuviésemos usando ActiveRecord.
class PostRelation < Array
# No necesitamos cambiar el sitio
attr_reader :site
def initialize(site:)
@site = site
# Proseguimos la inicialización sin valores por defecto
super()
end
# Genera un artículo nuevo con los parámetros que le pasemos y lo suma
# al array
def build(**args)
2019-08-08 19:26:47 +00:00
args[:lang] ||= I18n.locale
args[:document] ||= build_document(collection: args[:lang])
2019-08-08 19:26:47 +00:00
args[:layout] = build_layout(args[:layout])
post = Post.new(site: site, **args)
self << post
post
end
def create(**args)
2020-09-29 21:22:28 +00:00
post = build(**args)
post.save
post
end
alias sort_by_generic sort_by
2019-11-07 16:06:40 +00:00
alias sort_by_generic! sort_by!
# Permite ordenar los artículos por sus atributos
#
# XXX: Prestar atención cuando estamos mezclando artículos con
# diferentes tipos de atributos.
def sort_by(*attrs)
sort_by_generic do |post|
2019-11-07 16:06:40 +00:00
attrs.map do |attr|
# TODO: detectar el tipo de atributo faltante y obtener el valor
# por defecto para hacer la comparación
if post.attributes.include? attr
post.public_send(attr).value
else
0
end
2019-11-07 16:06:40 +00:00
end
end
end
def sort_by!(*attrs)
replace sort_by(*attrs)
end
alias find_generic find
2020-01-02 23:29:04 +00:00
# Encontrar un post por su UUID
def find(id, uuid: false)
find_generic do |p|
2020-01-02 23:29:04 +00:00
if uuid
p.uuid.value == id
else
p.id == id
end
end
end
# Encuentra el primer post por el valor de los atributos
#
# @param [Hash]
# @return [Post]
def find_by(**args)
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
#
# TODO: Implementar caché
#
# @param [Hash] Mapa de atributo => valor. Valor puede ser un Array
# de valores
# @return [PostRelation]
def where(**args)
return self if args.empty?
PostRelation[*select do |post|
result = args.map do |attr, value|
next unless post.attribute?(attr)
attribute = post.public_send(attr)
# TODO: Si el valor del atributo también es un Array deberíamos
# cruzar ambas.
case value
when Array then value.include? attribute.value
else
case attribute.value
when Array then attribute.value.include? value
else attribute.value == value
end
end
end.compact
# Un Array vacío devuelve true para all?
!result.empty? && result.all?
end]
end
# Intenta guardar todos y devuelve true si pudo
def save_all(validate: true)
map do |post|
post.save(validate: validate)
end.all?
end
2019-08-08 19:26:47 +00:00
private
def build_layout(layout = nil)
2019-08-08 19:26:47 +00:00
return layout if layout.is_a? Layout
2019-10-31 20:34:23 +00:00
site.layouts[layout.try(:to_sym) || :post]
2019-08-08 19:26:47 +00:00
end
# Devuelve una colección Jekyll que hace pasar el documento
def build_collection(label:)
Jekyll::Collection.new(site.jekyll, label.to_s)
2019-08-08 19:26:47 +00:00
end
# Un documento borrador con algunas propiedades por defecto
def build_document(collection:)
col = build_collection(label: collection)
doc = Jekyll::Document.new('', site: site.jekyll, collection: col)
2019-08-08 19:26:47 +00:00
doc.data['date'] = Date.today.to_time
doc
end
end