Created
February 17, 2023 16:56
-
-
Save copiousfreetime/9e87ba0ea5bc3b95d05415ca720ce04c to your computer and use it in GitHub Desktop.
Revisions
-
copiousfreetime created this gist
Feb 17, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,99 @@ module Searchable extend ActiveSupport::Concern included do include PgSearch::Model class_attribute :searchable_attributes, default: [] class_attribute :searchable_internal_attributes, default: [] multisearchable against: [ :searchable_attributes_text, :custom_searchable_text ], # See `internal_content` method below additional_attributes: -> (doc) { { internal_content: doc.internal_content } }, internal_against: [ :searchable_internal_attributes_text, :custom_internal_searchable_text ] end # Helper method so that Models can search just themselves from within the # multisearch index class_methods do def search_scope(q) PgSearch::Document.search(q).where(searchable_type: self.base_class.name) end def search(q) # use select here instead of pluck because it will make it a single query # instead of 2 queries self.where(id: search_scope(q).select(:searchable_id)) end def internal_search_scope(q) PgSearch::Document.internal_search(q).where(searchable_type: self.base_class.name) end def internal_search(q) self.where(id: internal_search_scope(q).select(:searchable_id)) end end # Meta programming so that modles can just set an class attribute of all the # attributes that are searchable # def searchable_attributes_text Array.new.tap do |a| searchable_attributes.each do |f| a << self.send(f) end end.compact.join(" ") end def related_searchable_objects [] end def custom_searchable_text Array.new.tap do |a| related_searchable_objects.each do |related| a << related_object_searchable_text(related) end end.compact.join(" ") end def related_object_searchable_text(related) return nil unless related.present? return nil unless related.kind_of?(Searchable) return related.searchable_attributes_text end # Basically equivalent to PgSearch::Mutisearchable#searchable_text def internal_content pg_search_multisearchable_options[:internal_against].map do |symbol| send(symbol) end.compact.join(" ") end def searchable_internal_attributes_text Array.new.tap do |a| searchable_internal_attributes.each do |f| a << self.send(f) end end.compact.join(" ") end def custom_internal_searchable_text Array.new.tap do |a| related_searchable_objects.each do |related| a << related_object_searchable_internal_text(related) end end.compact.join(" ") end def related_object_searchable_internal_text(related) return nil unless related.present? return nil unless related.kind_of?(Searchable) return related.searchable_internal_attributes_text end end