【问题标题】:Spree search filter for properties and variants属性和变体的大礼包搜索过滤器
【发布时间】:2013-02-13 11:58:12
【问题描述】:

我正在运行 Spree 1.3.1,并且正在尝试自定义分类显示页面。

我希望它返回当前分类单元中包含的产品,最终按属性或选项值过滤。

例如,假设我正在查看内衣系列的分类。 我想通过提供一定的尺寸(option_type)来过滤显示的产品。 在这种情况下,我应该只列出具有要求尺寸的变体的产品。

我还希望能够按“适合”属性过滤产品。 通过滑动配合过滤,我应该能够仅列出当前分类单元中具有所需属性的产品。

这是 Taxon 控制器的显示操作:

Spree::TaxonsController.class_eval do

    def show
      @taxon = Spree::Taxon.find_by_permalink!(params[:id])
      return unless @taxon

      @searcher = Spree::Config.searcher_class.new(params)
      @searcher.current_user = try_spree_current_user
      @searcher.current_currency = current_currency
      @products = @searcher.retrieve_products

      respond_with(@taxon)
    end


end

我应该如何修改它以满足我的需要?

【问题讨论】:

    标签: ruby-on-rails spree


    【解决方案1】:

    我部分解决了这个问题。

    我发现我需要让控制器保持原样,魔法是在我添加了这个新产品过滤器的 lib/spree/product_filters.rb 文件中完成的:

      if Spree::Property.table_exists?
        Spree::Product.add_search_scope :fit_any do |*opts|
          conds = opts.map {|o| ProductFilters.fit_filter[:conds][o]}.reject {|c| c.nil?}
          scope = conds.shift
          conds.each do |new_scope|
            scope = scope.or(new_scope)
          end
          Spree::Product.with_property("fit").where(scope)
        end
    
        def ProductFilters.fit_filter
          fit_property = Spree::Property.find_by_name("fit")
          fits = Spree::ProductProperty.where(:property_id => fit_property).pluck(:value).uniq
          pp = Spree::ProductProperty.arel_table
          conds = Hash[*fits.map { |b| [b, pp[:value].eq(b)] }.flatten]
          { :name   => "Fits",
            :scope  => :fit_any,
            :conds  => conds,
            :labels => (fits.sort).map { |k| [k, k] }
          }
        end
      end
    

    然后我将新过滤器添加到 Taxon 模型装饰器中:

    Spree::Taxon.class_eval do
    
      def applicable_filters
        fs = []
        fs << Spree::Core::ProductFilters.fit_filter if Spree::Core::ProductFilters.respond_to?(:fit_filter)
        fs
      end  
    
    
    end
    

    我仍然没有找到如何为具有特定选项值的变体创建过滤器。

    【讨论】:

      【解决方案2】:

      你说的是数值过滤,我写了一个选项范围的过滤器:

      def ProductFilters.ov_range_test(range1, range2)
        ov = Arel::Table.new("spree_option_values")
        cast = Arel::Nodes::NamedFunction.new "CAST", [ ov[:presentation].as("integer")]
        comparaisons = cast.in(range1..range2)
        comparaisons
      end
      
      Spree::Product.add_search_scope :screenSize_range_any do |*opts|
        conds = opts.map {|o| Spree::ProductFilters.screenSize_filter[:conds][o]}.reject {|c| c.nil?}
        scope = conds.shift
        conds.each do |new_scope|
          scope = scope.or(new_scope)
        end
        option_values=Spree::OptionValue.where(scope).joins(:option_type).where(OptionType.table_name => {:name => "tailleEcran"}).pluck("#{OptionValue.table_name}.id")
        Spree::Product.where("#{Product.table_name}.id in (select product_id from #{Variant.table_name} v left join spree_option_values_variants ov on ov.variant_id = v.id where ov.option_value_id in (?))", option_values)
      end
      
      def ProductFilters.screenSize_filter
        conds = [ [ "20p ou moins",ov_range_test(0,20)],
        [ "20p - 30p",ov_range_test(20,30)],
        [ "30p - 40p" ,ov_range_test(30,40)],
        [ "40p ou plus",ov_range_test(40,190)]]
        { :name   => "taille",
          :scope  => :screenSize_range_any,
          :options => :tailleEcran,
          :conds  => Hash[*conds.flatten],
          :labels => conds.map {|k,v| [k,k]}
        }
      end
      

      对于离散的特定值,您也可以看到这个: https://gist.github.com/Ranger-X/2511088

      【讨论】:

      • 大家好。有没有关于这个习俗的文件狂欢说。谢谢 :) 。我读了你的答案,但我不明白我如何定义一个
      猜你喜欢
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多