9

Spree 1.3.1 を実行していて、Taxon の表示ページをカスタマイズしようとしています。

現在の分類群に含まれる製品を返し、最終的にプロパティまたはオプション値でフィルタリングしたいと考えています。

たとえば、下着コレクションの分類群を見ているとしましょう。特定のサイズ (option_type) を指定して、表示される製品をフィルタリングしたいと思います。この場合、リクエストされたサイズのバリエーションがある商品のみをリストする必要があります。

また、「適合」プロパティで製品をフィルタリングできるようにしたいと考えています。スリップフィットでフィルタリングすると、必要なプロパティを持つ現在の分類群内の製品のみを一覧表示できるはずです。

これは、Taxon コントローラの show アクションです。

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

ニーズに合わせてどのように変更すればよいですか?

4

2 に答える 2

7

質問を部分的に解決しました。

コントローラーをそのままにしておく必要があることがわかりました。魔法は、この新しい製品フィルターを追加した 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

それでも、特定のオプション値を持つバリアントのフィルターを作成する方法がわかりません。

于 2013-02-17T15:03:08.373 に答える
3

あなたは数値のフィルタリングについて話しますが、私はオプション範囲のフィルターを書きました:

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

于 2013-03-12T12:36:57.133 に答える