如何覆盖lib / spree / search / base.rb

时间:2012-02-16 17:12:56

标签: ruby-on-rails ruby ruby-on-rails-3 spree acts-as-taggable-on

我需要覆盖此类中的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

然后在application.rb中的Spree::Config.searcher = TagsSearch ...

我甚至尝试通过在应用程序内的同一目录结构中放置副本来完全替换文件,或者没有任何反应,或者我得到上述错误......

我要做的是整合acts_as_taggable_on已完成并正常工作,但搜索显然不会返回这些标记的结果......

编辑:好的,所以在Steph的回答之后我尝试过:

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
<{1>}中的

app/models/search/tags_search.rb

中的Steph代码建议

和此:

lib/spree/search/tags_search.rb
config.to_prepare do Spree::Core::Search::Base.send(:include, TagsSearch) end

中的

启动服务器时会产生以下结果:

config/environments/development.rb

2 个答案:

答案 0 :(得分:2)

  

我需要覆盖此类中的get_products_conditions_for方法,这样做的最佳方法是什么?

在这种特殊情况下,我继承了该类并覆盖了所需的方法。

如同施普雷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
    

    注意:以上是修改狂欢中搜索者类的规定方法

答案 1 :(得分:0)

我建议使用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是一种很好/干净的方法来扩展给定类的类和实例方法。
  • Alias保留Spree方法。如果你不想这样做,你不必这样做。

在开发过程中,因为默认配置设置导致非缓存类但不重新加载lib /模块,您可能需要在config / environments / development.rb中添加它:

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