Jonathan Bennett

Adding multi-model search, with just a bit of complexity

Last time we used pg_search to search a single model, but we also have the option to search multiple models. To support multisearch we will need to:

  1. Add a backing table that search is performed against
  2. Specify configuration for all multisearch-able models
  3. Rebuild Search Index
  4. Profit!

1. Add Backing Table

Fortunately, this is quick and painless. pg_search includes a migration for us se we just need to copy that over and run it:

rails g pg_search:migration:multisearch
rake db:migrate

2. Configure Models

pg_search needs to know what to index and search against and keep track of updates to the model. This is done with the multisearchable method:

class MyModel < ApplicationRecord
	include PgSearch::Model
	
	multisearchable against: [:title, :description]
end

class MyOtherModel < ApplicationRecord
	include PgSearch::Model
	
	multisearchable against: [:title, :body]
end

3. Rebuild Search Index

With multisearch, a index table is created of all searchable content. Any time you add or change the fields configured with multisearchable, you need to rebuild the search index so that it will update with new information.

PgSearch::Multisearch.rebuild(MyModel)
PgSearch::Multisearch.rebuild(MyOtherModel)

4. Profit!

With pg_search installed, configured, and re-built, its now ready to be used. All we need to do is update the global searches to use multisearch instead of the single model search:

# app/controllers/global_searches_controller.rb
class GlobalSearchesController < ApplicationController
	def show
		@results = PgSearch.multisearch(params[:q])
	end
end

multisearch returns an ActiveRecord::Relation, so you can chain it with other options, like limit, and use it anywhere you would normally, such as with pagination.