Skip to content

Integration with PgSearch

Sam Pohlenz edited this page Oct 28, 2020 · 2 revisions

Using the PgSearch gem, you can take advantage of PostgreSQL's full text search capabilities without running an additional search engine process.

Model

class Movie < ApplicationRecord
  scope :between, ->(from, to) { where("year >= :from AND year <= :to", from: from, to: to) }

  include PgSearch
  pg_search_scope :pg_search, against: [:title, :director, :cast, :genre, :notes], using: { tsearch: { prefix: true, tsvector_column: "tsv" } }
end

Admin

Trestle.resource(:movies) do
  collection do
    Movie.order(title: :asc)
  end

  search do |query|
    query ? collection.pg_search(query) : collection
  end

  scope :all, default: true
  scope :year_1900_1949, -> { Movie.between(1900, 1949) }, label: "1900-1949"
  scope :year_1950_1999, -> { Movie.between(1950, 1999) }, label: "1950-1999"
  scope :year_2000_2049, -> { Movie.between(2000, 2049) }, label: "2000-2049"
end

Migration (Required)

class AddTsvectorIndexToMovies < ActiveRecord::Migration[5.1]
  def change
    add_column :movies, :tsv, :tsvector
    add_index :movies, :tsv, using: 'gin'

    reversible do |dir|
      dir.up do
        execute <<-SQL
          CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON movies
          FOR EACH ROW EXECUTE PROCEDURE
          tsvector_update_trigger(tsv, 'pg_catalog.simple', title, director, cast, genre, notes);
        SQL

        # Trigger re-index on existing movies
        execute("UPDATE movies SET id = id")
      end

      dir.down { execute("DROP TRIGGER IF EXISTS tsvectorupdate ON movies") }
    end
  end
end
Clone this wiki locally