1

I have a question regarding pg_search: I installed the gem on solidus 2.9 and added a product_decorator.rb model like this:

Spree::Product.class_eval do
  include PgSearch::Model

  pg_search_scope :search, against: [:name, :description, :meta_description, :meta_keywords],
    using: {tsearch: {dictionary: "english"}}

end

It works fine in rails console.

How can I make it work when I use the search field in solidus' frontend? I tried adding it to the product controller but can't seem to make it work. Thanks!

UPDATE

So after kennyadsl's comments I have this:

#lib/mystore/products_search.rb

module MyStore
  class ProductSearch < Spree::Core::Search::Base

    def retrieve_products
      Spree::Product.pg_search
    end
  end
end
#models/spree/product_decorator.rb

Spree::Product.class_eval do
  include PgSearch::Model

  pg_search_scope :search, against: [:name, :description, :meta_description, :meta_keywords], using: {tsearch: {dictionary: "english"}}

  def self.text_search(keywords)
        if keywords.present?
      search(keywords)
    else
      Spree::Product.all
    end
  end       

end
#controllers/products_controller.rb

def index
  @searcher = build_searcher(params.merge(include_images: true))
  @products = @searcher.retrieve_products(params)
end
Ignacio
  • 37
  • 1
  • 9

1 Answers1

1

By default, products search is performed through the Spree::Core::Search::Base class, but it's configurable so you can create your own class that inherits from that one:

module Spree
  module Core
    module Search
      class PgSearch < Spree::Core::Search::Base
        def retrieve_products
          PgSearch.multisearch(...)
        end
      end
    end
  end
end

To see what's available in that class you can refer to the original implementation here:

https://github.com/solidusio/solidus/blob/eff22e65691a64d2ce0bf8a919d8456010360753/core/lib/spree/core/search/base.rb

Once you've added your own logic, you can use the new class to perform search by adding this line into a config/initializers/spree.rb:

Spree::Config.searcher_class = Spree::Core::Search::PgSearch

UPDATE

After some back and forth with Ignacio, this is a working version to perform a basic search with PgSearch in the Solidus storefront:

# app/models/spree/product_decorator.rb

Spree::Product.class_eval do
  include PgSearch::Model

  pg_search_scope :keywords, 
    against: [:name, :description, :meta_description, :meta_keywords],
    using: { tsearch: { dictionary: "english" } }
end
# lib/spree/core/search/pg_search.rb

module Spree
  module Core
    module Search
      class PgSearch < Spree::Core::Search::Base
        def retrieve_products
          Spree::Product.pg_search_by_keywords(@properties[:keywords])
        end
      end
    end
  end
end
# config/initializers/spree.rb

Spree::Config.searcher_class = Spree::Core::Search::PgSearch
kennyadsl
  • 706
  • 6
  • 10
  • Thanks @kennyadsl....I did what you suggested (but using pg_search_scope instead of multisearch). I'm still not clear how to add the param[:keywords] to the search, so it shows the pg_search results when a query is sumbitted in the search form. As a test, I hard coded a search term like this: `Spree::Product.search('rails')` and that works. How can I add the params? Thanks – Ignacio Sep 05 '19 at 23:39
  • In the `Spree::Core::Search::PgSearch` class, you have access to `params[:keyword]` through `@properties[:keywords]`. It is set here: https://github.com/solidusio/solidus/blob/eff22e65691a64d2ce0bf8a919d8456010360753/core/lib/spree/core/search/base.rb#L107 during instance initialization. – kennyadsl Sep 06 '19 at 08:59
  • Thanks again @kennyadsl. Sorry but I still don't quite understand. I updated my question above to show what I have in my models/spree/product_decorator.rb, in my lib/mystore/product_search.rb and in my products_controller.rb...I'd really appreciate if you could take a look and tell me what I'm doing wrong. If I try to pass the param, then when showing the products page without a search, gives me 'wrong number of arguments (given 0, expected 1)', if I remove the param, then I get 'undefined method `[]' for nil:NilClass' Sorry again for asking so many questions. – Ignacio Sep 08 '19 at 00:38