# frozen_string_literal: true class Post # Vuelve indexables a los Posts module Indexable extend ActiveSupport::Concern included do # Indexa o reindexa el Post after_save :index! after_destroy :remove_from_index! # Devuelve una versión indexable del Post # # @return [IndexedPost] def to_index IndexedPost.find_or_initialize_by(post_id: uuid.value, site_id: site.id).tap do |indexed_post| indexed_post.layout = layout.name indexed_post.path = path.basename indexed_post.locale = locale.value indexed_post.dictionary = IndexedPost.to_dictionary(locale: locale.value) indexed_post.title = title.value indexed_post.front_matter = indexable_front_matter indexed_post.content = indexable_content indexed_post.created_at = date.value indexed_post.order = attribute?(:order) ? order.value : 0 end end # Indexa o reindexa el Post # # @return [Boolean] def index! to_index.save end def remove_from_index! to_index.destroy.destroyed? end private # Los metadatos que se almacenan como objetos JSON. Empezamos con # las categorías porque se usan para filtrar en el listado de # artículos. # # @return [Hash] def indexable_front_matter {}.tap do |ifm| ifm[:usuaries] = usuaries.map(&:id) ifm[:draft] = attribute?(:draft) ? draft.value : false ifm[:categories] = categories.indexable_values if attribute? :categories end end # Devuelve un documento indexable en texto plano # # XXX: No memoizamos para permitir actualizaciones, aunque # probablemente se indexe una sola vez. # # @return [String] def indexable_content indexable_attributes.map do |attr| self[attr].to_s.tr("\n", ' ') end.join("\n").squeeze("\n") end def indexable_attributes @indexable_attributes ||= attributes.select do |attr| self[attr].indexable? end end end end end