Question

I need to select available taxons and their childs.

I'm using this custom rule:

module Spree
  class Promotion
    module Rules

      class TaxonPromotionRule < Spree::PromotionRule

        has_and_belongs_to_many :taxon, class_name: '::Spree::Taxon', join_table: 'spree_taxons_promotion_rules', foreign_key: 'promotion_rule_id'
        validate :only_one_promotion_per_product

        MATCH_POLICIES = %w(any all)
        preference :match_policy, :string, default: MATCH_POLICIES.first

        # scope/association that is used to test eligibility
        def eligible_taxons
          taxon
        end

        def applicable?(promotable)
          promotable.is_a?(Spree::Order)
        end

        def eligible?(order, options = {})
          return false if eligible_taxons.empty?
          if preferred_match_policy == 'all'
            eligible_taxons.all? {|p| order.products.include_taxon?(p) }
          else
            order.products.any? {|p| eligible_taxons.any? {|t| t.include_product?(p)} }
          end
        end

        def taxon_ids_string
          taxon_ids.join(',')
        end

        def taxon_ids_string=(s)
          self.taxon_ids = s.to_s.split(',').map(&:strip)
        end

        private

          def only_one_promotion_per_product
            if Spree::Promotion::Rules::TaxonPromotionRule.all.map(&:taxon).flatten.uniq!
              errors[:base] << "You can't create two promotions for the same product"
            end
          end

      end

    end
  end
end

and decorator:

Spree::Taxon.class_eval do
  def include_product? p
    products.include? p
  end
end

I want eligible_taxons to be taxon from rules table and all child id. So if I set some root category this rule would apply for all child categories. I hope my question is understandable and clear. :)

Was it helpful?

Solution

Found it. Looks complicated for a newbie (me) on RoR. But here it is:

def eligible_taxons
  taxon_with_childs = []
  taxon.each { |t| t.self_and_descendants.each{|s| taxon_with_childs << s} }
  taxon_with_childs.uniq
end

It builds new list of descendants and self. More details about these functions are here https://github.com/collectiveidea/awesome_nested_set/blob/master/lib/awesome_nested_set/model/relatable.rb

Because after building this list some rows are identical and repeats few times we return only unique taxon_with_childs.uniq

This probably not the best performing algorithm but it does what I needed and fits well with amount of data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top