From 9175504bc189f3b7f621dd3f6b4fa6d141d48462 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 6 Aug 2020 11:00:49 +0100 Subject: [PATCH] Bring taxon, taxonomy and classification from spree_core --- app/models/spree/classification.rb | 7 +++ app/models/spree/taxon.rb | 73 ++++++++++++++++++++++++++++++ app/models/spree/taxonomy.rb | 22 +++++++++ spec/models/spree/taxon_spec.rb | 49 ++++++++++++++++++++ spec/models/spree/taxonomy_spec.rb | 18 ++++++++ 5 files changed, 169 insertions(+) create mode 100644 app/models/spree/classification.rb create mode 100644 app/models/spree/taxon.rb create mode 100644 app/models/spree/taxonomy.rb create mode 100644 spec/models/spree/taxonomy_spec.rb diff --git a/app/models/spree/classification.rb b/app/models/spree/classification.rb new file mode 100644 index 0000000000..7f7b1579ec --- /dev/null +++ b/app/models/spree/classification.rb @@ -0,0 +1,7 @@ +module Spree + class Classification < ActiveRecord::Base + self.table_name = 'spree_products_taxons' + belongs_to :product, class_name: "Spree::Product" + belongs_to :taxon, class_name: "Spree::Taxon" + end +end diff --git a/app/models/spree/taxon.rb b/app/models/spree/taxon.rb new file mode 100644 index 0000000000..2d9cbb4a4d --- /dev/null +++ b/app/models/spree/taxon.rb @@ -0,0 +1,73 @@ +module Spree + class Taxon < ActiveRecord::Base + acts_as_nested_set dependent: :destroy + + belongs_to :taxonomy, class_name: 'Spree::Taxonomy', :touch => true + has_many :classifications, dependent: :delete_all + has_many :products, through: :classifications + + before_create :set_permalink + + validates :name, presence: true + + has_attached_file :icon, + styles: { mini: '32x32>', normal: '128x128>' }, + default_style: :mini, + url: '/spree/taxons/:id/:style/:basename.:extension', + path: ':rails_root/public/spree/taxons/:id/:style/:basename.:extension', + default_url: '/assets/default_taxon.png' + + include Spree::Core::S3Support + supports_s3 :icon + + include Spree::Core::ProductFilters # for detailed defs of filters + + # indicate which filters should be used for a taxon + # this method should be customized to your own site + def applicable_filters + fs = [] + # fs << ProductFilters.taxons_below(self) + ## unless it's a root taxon? left open for demo purposes + + fs << Spree::Core::ProductFilters.price_filter if Spree::Core::ProductFilters.respond_to?(:price_filter) + fs << Spree::Core::ProductFilters.brand_filter if Spree::Core::ProductFilters.respond_to?(:brand_filter) + fs + end + + # Return meta_title if set otherwise generates from root name and/or taxon name + def seo_title + if meta_title + meta_title + else + root? ? name : "#{root.name} - #{name}" + end + end + + # Creates permalink based on Stringex's .to_url method + def set_permalink + if parent.present? + self.permalink = [parent.permalink, (permalink.blank? ? name.to_url : permalink.split('/').last)].join('/') + else + self.permalink = name.to_url if permalink.blank? + end + end + + # For #2759 + def to_param + permalink + end + + def active_products + scope = products.active + scope + end + + def pretty_name + ancestor_chain = self.ancestors.inject("") do |name, ancestor| + name += "#{ancestor.name} -> " + end + ancestor_chain + "#{name}" + end + + end +end diff --git a/app/models/spree/taxonomy.rb b/app/models/spree/taxonomy.rb new file mode 100644 index 0000000000..c5b4a5e965 --- /dev/null +++ b/app/models/spree/taxonomy.rb @@ -0,0 +1,22 @@ +module Spree + class Taxonomy < ActiveRecord::Base + validates :name, presence: true + + has_many :taxons + has_one :root, -> { where parent_id: nil }, class_name: "Spree::Taxon", dependent: :destroy + + after_save :set_name + + default_scope -> { order("#{self.table_name}.position") } + + private + def set_name + if root + root.update_column(:name, name) + else + self.root = Taxon.create!(taxonomy_id: id, name: name) + end + end + + end +end diff --git a/spec/models/spree/taxon_spec.rb b/spec/models/spree/taxon_spec.rb index 54a0069da9..9055b94aea 100644 --- a/spec/models/spree/taxon_spec.rb +++ b/spec/models/spree/taxon_spec.rb @@ -2,6 +2,8 @@ require 'spec_helper' module Spree describe Taxon do + let(:taxon) { Spree::Taxon.new(:name => "Ruby on Rails") } + let(:e) { create(:supplier_enterprise) } let!(:t1) { create(:taxon) } let!(:t2) { create(:taxon) } @@ -46,5 +48,52 @@ module Spree end.to change { taxon2.reload.updated_at } end end + + context "set_permalink" do + it "should set permalink correctly when no parent present" do + taxon.set_permalink + taxon.permalink.should == "ruby-on-rails" + end + + it "should support Chinese characters" do + taxon.name = "你好" + taxon.set_permalink + taxon.permalink.should == 'ni-hao' + end + + context "with parent taxon" do + before do + taxon.stub :parent_id => 123 + taxon.stub :parent => mock_model(Spree::Taxon, :permalink => "brands") + end + + it "should set permalink correctly when taxon has parent" do + taxon.set_permalink + taxon.permalink.should == "brands/ruby-on-rails" + end + + it "should set permalink correctly with existing permalink present" do + taxon.permalink = "b/rubyonrails" + taxon.set_permalink + taxon.permalink.should == "brands/rubyonrails" + end + + it "should support Chinese characters" do + taxon.name = "我" + taxon.set_permalink + taxon.permalink.should == "brands/wo" + end + end + end + + # Regression test for Spree #2620 + context "creating a child node using first_or_create" do + let(:taxonomy) { create(:taxonomy) } + + it "does not error out" do + pending "breaks in Rails 4 with postgres, see https://github.com/rails/rails/issues/10995" + expect { taxonomy.root.children.where(:name => "Some name").first_or_create }.not_to raise_error + end + end end end diff --git a/spec/models/spree/taxonomy_spec.rb b/spec/models/spree/taxonomy_spec.rb new file mode 100644 index 0000000000..f825f49764 --- /dev/null +++ b/spec/models/spree/taxonomy_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe Spree::Taxonomy do + context "#destroy" do + before do + @taxonomy = create(:taxonomy) + @root_taxon = @taxonomy.root + @child_taxon = create(:taxon, :taxonomy_id => @taxonomy.id, :parent => @root_taxon) + end + + it "should destroy all associated taxons" do + @taxonomy.destroy + expect{ Spree::Taxon.find(@root_taxon.id) }.to raise_error(ActiveRecord::RecordNotFound) + expect{ Spree::Taxon.find(@child_taxon.id) }.to raise_error(ActiveRecord::RecordNotFound) + end + end +end +