Как переопределить lib / spree / search / base.rb - PullRequest
4 голосов
/ 16 февраля 2012

Мне нужно переопределить метод get_products_conditions_for в этом классе, каков наилучший способ сделать это?

Я пытался добавить это в инициализатор:

Spree::Search::Base.class_eval do
    def get_products_conditions_for(base_scope, query)
      base_scope.like_any([:name, :description], query.split) | base_scope.joins("JOIN taggings on taggings.taggable_id = spree_products.id JOIN tags on tags.id = taggings.tag_id").where("tags.name = ?", query.split)
    end
end

, которыйприводит к этой ошибке при запуске сервера: uninitialized constant Spree::Search (NameError)

Я также пытался добавить это в "/lib/spree/search/base.rb" и "/lib/spree/search/tags_search.rb"

module Spree::Search
  class TagsSearch < Spree::Search::Base

    def get_products_conditions_for(base_scope, query)
      base_scope.like_any([:name, :description], query.split) | base_scope.joins("JOIN taggings on taggings.taggable_id = spree_products.id JOIN tags on tags.id = taggings.tag_id").where("tags.name = ?", query.split)
    end

  end
end

, а затем Spree::Config.searcher = TagsSearch в application.rb ...

Я даже попытался полностью заменить файл, разместив реплику в той же структуре каталогов в приложении,либо ничего не происходит, либо я получаю упомянутые ошибки ...

Я пытаюсь интегрировать acts_as_taggable_on, что сделано и работает, однако поиск, очевидно, не возвращает результаты по этим тегам ...

РЕДАКТИРОВАТЬ: Хорошо, поэтому после ответа Стефа я попытался:

module Spree::Search
  class TagsSearch < Spree::Search::Base

    def get_products_conditions_for(base_scope, query)
      base_scope.like_any([:name, :description], query.split) | base_scope.joins("JOIN taggings on taggings.taggable_id = spree_products.id JOIN tags on tags.id = taggings.tag_id").where("tags.name = ?", query.split)
    end

  end
end

в app/models/search/tags_search.rb и предложение кода Стефа в lib/spree/search/tags_search.rb

и это:

config.to_prepare do
    Spree::Core::Search::Base.send(:include, TagsSearch)
  end

in config/environments/development.rb

, что приводит к следующему при запуске сервера:

uninitialized constant TagsSearch (NameError)

Ответы [ 2 ]

2 голосов
/ 25 февраля 2016

Мне нужно переопределить метод get_products_conditions_for в этом классе, какой лучший способ сделать это?

В этом конкретном случае я унаследовал класс и переопределил требуемый метод.

Как и в Spree 3,

  1. В config / initializers / spree.rb, блок Spree.config config.searcher_class= Spree::MySearch
  2. Создать файл lib / spree/my_search.rb со следующим содержимым:

    module Spree
      class MySearch < Spree::Core::Search::Base
        def method_to_be_overridden
          # Your new definition here
        end
      end
    end
    

    Примечание. Выше приведен предписанный способ изменения класса поисковика в Spree

0 голосов
/ 17 февраля 2012

Я бы рекомендовал использовать ActiveSupport :: Concern , который может выглядеть примерно так:

module YourAwesomeModule
  extend ActiveSupport::Concern

  included do
    alias :spree_get_products_conditions_for :get_products_conditions_for
    def get_products_conditions_for(base_scope, query)
      custom_get_products_conditions_for(base_scope, query)
    end
  end

  module InstanceMethods
    def custom_get_products_conditions_for(base_scope, query)
      #your stuff
    end 
  end
end

Spree::Core::Search::Base.send(:include, YourAwesomeModule)

Это делает несколько вещей:

  • Использование ActiveSupport :: Concern - это хороший / чистый способ расширения класса и методов экземпляра для данного класса.
  • Псевдоним сохраняет метод Spree.Вам не нужно делать этот бит, если вы этого не хотите.

Во время разработки, потому что настройки конфигурации по умолчанию приводят к не кэшированию классов, но не перезагружают lib / modules, вам может понадобитьсячтобы добавить это в config / environment / development.rb:

config.to_prepare do
  Spree::Core::Search::Base.send(:include, YourAwesomeModule)
end
...