Как переопределить lib/spree/search/base.rb

Мне нужно переопределить метод 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, что сделано и работает, однако поиск, очевидно, не возвращает результатов по этим тегам...

EDIT: Итак, после ответа Стефа я попробовал:

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)


person Chris Edwards    schedule 16.02.2012    source источник
comment
Как у вас установлен Spree? драгоценный камень? плагин? Похоже, проблема в порядке загрузки веселья.   -  person siannopollo    schedule 17.02.2012
comment
Как драгоценный камень, не думайте, что он приходит как что-то еще...   -  person Chris Edwards    schedule 17.02.2012


Ответы (2)


Мне нужно переопределить метод 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

person Sriharsha    schedule 25.02.2016

Я бы рекомендовал использовать 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. Вам не обязательно делать это, если вы не хотите.

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

config.to_prepare do
  Spree::Core::Search::Base.send(:include, YourAwesomeModule)
end
person Community    schedule 17.02.2012
comment
Попробуйте удалить пространство имен и наследование в TagSearch. Он не обязательно должен принадлежать пространству имен Spree::Search и не должен наследоваться от Spree::Search::Base. В моем примере Rails.root/lib/your_awesome_module.rb будет содержать модуль, который я описал. И вам все еще нужно включить ActiveSupport::concern и включенные биты. - person ; 18.02.2012
comment
Простите за поздний ответ. У меня есть ваш код в lib/awesome_search.rb и блок config.to_prepare в config/environments/development.rb, и я все еще получаю похожие ошибки: неинициализированная константа AwesomeSearch (NameError) - person Chris Edwards; 29.02.2012
comment
Я знаю, что это старо, но я хотел бы отметить, что я тоже пытался сделать что-то подобное и получил постоянную ошибку Uninitialized для моего модуля при установке searcher_class в моем инициализаторе веселья. У меня был модуль поиска в Spree::Core::Search, и он работал, когда я использовал config.searcher_class = Spree::Core::Search::MySearch. - person biagidp; 10.01.2014