2021-05-06 15:52:30 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
# La representación indexable de un artículo
|
|
|
|
class IndexedPost < ApplicationRecord
|
|
|
|
include PgSearch::Model
|
|
|
|
|
|
|
|
# La traducción del locale según Sutty al locale según PostgreSQL
|
|
|
|
DICTIONARIES = {
|
|
|
|
es: 'spanish',
|
|
|
|
en: 'english'
|
|
|
|
}.freeze
|
|
|
|
|
|
|
|
# TODO: Los indexed posts tienen que estar scopeados al idioma actual,
|
|
|
|
# no buscar sobre todos
|
|
|
|
pg_search_scope :search,
|
2021-05-14 19:59:47 +00:00
|
|
|
lambda { |locale, query|
|
|
|
|
{
|
|
|
|
against: :content,
|
|
|
|
query: query,
|
|
|
|
using: {
|
|
|
|
tsearch: {
|
|
|
|
dictionary: IndexedPost.to_dictionary(locale: locale),
|
|
|
|
tsvector_column: 'indexed_content'
|
|
|
|
},
|
|
|
|
trigram: {
|
|
|
|
word_similarity: true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-05-06 15:52:30 +00:00
|
|
|
|
2021-05-06 22:07:11 +00:00
|
|
|
# Trae los IndexedPost en el orden en que van a terminar en el sitio.
|
2021-05-14 19:59:47 +00:00
|
|
|
default_scope -> { order(order: :desc, created_at: :desc) }
|
|
|
|
scope :in_category, ->(category) { where("front_matter->'categories' ? :category", category: category.to_s) }
|
|
|
|
scope :by_usuarie, ->(usuarie) { where("front_matter->'usuaries' @> :usuarie::jsonb", usuarie: usuarie.to_s) }
|
2021-05-06 22:07:11 +00:00
|
|
|
|
2023-10-06 12:59:42 +00:00
|
|
|
# Trae todos los valores únicos para un atributo
|
|
|
|
#
|
|
|
|
# @param :attribute [String,Symbol]
|
|
|
|
# @return [Array]
|
|
|
|
scope :everything_of, ->(attribute) do
|
|
|
|
where('front_matter ? :attribute', attribute: attribute)
|
|
|
|
.pluck(
|
|
|
|
Arel.sql(
|
|
|
|
ActiveRecord::Base::sanitize_sql(['front_matter -> :attribute', attribute: attribute])
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.flatten.uniq
|
|
|
|
end
|
|
|
|
|
2021-05-06 15:52:30 +00:00
|
|
|
belongs_to :site
|
|
|
|
|
2023-10-06 12:54:25 +00:00
|
|
|
# La ubicación del Post en el disco
|
|
|
|
#
|
|
|
|
# @return [String]
|
|
|
|
def full_path
|
|
|
|
@full_path ||= File.join(site.path, "_#{locale}", "#{path}.markdown")
|
|
|
|
end
|
|
|
|
|
2023-10-06 12:56:12 +00:00
|
|
|
# La colección
|
|
|
|
#
|
|
|
|
# @return [Jekyll::Collection]
|
|
|
|
def collection
|
|
|
|
site.collections[locale.to_s]
|
|
|
|
end
|
|
|
|
|
2023-10-06 12:57:21 +00:00
|
|
|
# Obtiene el documento
|
|
|
|
#
|
|
|
|
# @return [Jekyll::Document]
|
|
|
|
def document
|
|
|
|
@document ||= Jekyll::Document.new(full_path, site: site.jekyll, collection: collection)
|
|
|
|
end
|
|
|
|
|
2023-10-06 12:57:44 +00:00
|
|
|
# El Post
|
|
|
|
#
|
|
|
|
# @todo Decidir qué pasa si el archivo ya no existe
|
|
|
|
# @return [Post]
|
|
|
|
def post
|
|
|
|
@post ||= Post.new(document: document, site: site, layout: schema)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Devuelve el esquema de datos
|
|
|
|
#
|
|
|
|
# @todo Renombrar
|
|
|
|
# @return [Layout]
|
|
|
|
def schema
|
|
|
|
site.layouts[layout.to_sym]
|
|
|
|
end
|
|
|
|
|
2023-10-06 13:15:57 +00:00
|
|
|
# Existe físicamente?
|
|
|
|
#
|
|
|
|
# @return [Boolean]
|
|
|
|
def exist?
|
|
|
|
File.exist?(full_path)
|
|
|
|
end
|
|
|
|
|
2021-05-06 15:52:30 +00:00
|
|
|
# Convertir locale a direccionario de PG
|
|
|
|
#
|
|
|
|
# @param [String,Symbol]
|
|
|
|
# @return [String]
|
|
|
|
def self.to_dictionary(locale:)
|
|
|
|
DICTIONARIES[locale.to_sym] || 'simple'
|
|
|
|
end
|
|
|
|
end
|