如何在 Solidus 前端的搜索表单中添加 pg_search?

How to add pg_search to the seach form in Solidus frontend?

我有一个关于 pg_search 的问题: 我在 solidus 2.9 上安装了 gem 并添加了一个 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"}}

end

它在 rails 控制台中工作正常。

当我使用 solidus 前端的搜索字段时,如何让它工作?我尝试将它添加到产品控制器,但似乎无法正常工作。 谢谢!

更新

所以在 kennyadsl 的评论之后我有这个:

#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

默认情况下,产品搜索是通过 Spree::Core::Search::Base class 执行的,但它是可配置的,因此您可以创建自己的 class 继承自 class:

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

要查看 class 中的可用内容,您可以在此处参考原始实现:

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

一旦您添加了自己的逻辑,就可以使用新的 class 通过将此行添加到 config/initializers/spree.rb:

来执行搜索
Spree::Config.searcher_class = Spree::Core::Search::PgSearch

更新

在与 Ignacio 来回交流之后,这是一个可以在 Solidus 店面中使用 PgSearch 执行基本搜索的工作版本:

# 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