Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bye bye Spree] Bring models taxon and taxonomy from spree_core #5868

Merged
merged 8 commits into from
Sep 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions app/models/spree/classification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Spree
class Classification < ActiveRecord::Base
self.table_name = 'spree_products_taxons'
belongs_to :product, class_name: "Spree::Product", touch: true
belongs_to :taxon, class_name: "Spree::Taxon", touch: true

before_destroy :dont_destroy_if_primary_taxon

private

def dont_destroy_if_primary_taxon
return unless product.primary_taxon == taxon

errors.add :base, I18n.t(:spree_classification_primary_taxon_error, taxon: taxon.name,
product: product.name)
false
end
end
end
15 changes: 0 additions & 15 deletions app/models/spree/classification_decorator.rb

This file was deleted.

113 changes: 113 additions & 0 deletions app/models/spree/taxon.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# frozen_string_literal: true

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: :destroy
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

# Indicate which filters should be used for this taxon
def applicable_filters
[]
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_end].join('/')
elsif permalink.blank?
self.permalink = name.to_url
end
end

# For #2759
def to_param
permalink
end

def active_products
scope = products.active
scope
end

def pretty_name
ancestor_chain = ancestors.inject("") do |name, ancestor|
name += "#{ancestor.name} -> "
end
ancestor_chain + name.to_s
end

# Find all the taxons of supplied products for each enterprise, indexed by enterprise.
# Format: {enterprise_id => [taxon_id, ...]}
def self.supplied_taxons
taxons = {}

Spree::Taxon.
joins(products: :supplier).
select('spree_taxons.*, enterprises.id AS enterprise_id').
each do |t|
taxons[t.enterprise_id.to_i] ||= Set.new
taxons[t.enterprise_id.to_i] << t.id
end

taxons
end

# Find all the taxons of distributed products for each enterprise, indexed by enterprise.
# May return :all taxons (distributed in open and closed order cycles),
# or :current taxons (distributed in an open order cycle).
#
# Format: {enterprise_id => [taxon_id, ...]}
def self.distributed_taxons(which_taxons = :all)
ents_and_vars = ExchangeVariant.joins(exchange: :order_cycle).merge(Exchange.outgoing)
.select("DISTINCT variant_id, receiver_id AS enterprise_id")

ents_and_vars = ents_and_vars.merge(OrderCycle.active) if which_taxons == :current

taxons = Spree::Taxon
.select("DISTINCT spree_taxons.id, ents_and_vars.enterprise_id")
.joins(products: :variants_including_master)
.joins("
INNER JOIN (#{ents_and_vars.to_sql}) AS ents_and_vars
ON spree_variants.id = ents_and_vars.variant_id")

taxons.each_with_object({}) do |t, ts|
ts[t.enterprise_id.to_i] ||= Set.new
ts[t.enterprise_id.to_i] << t.id
end
end

private

def permalink_end
return name.to_url if permalink.blank?

permalink.split('/').last
end
end
end
47 changes: 0 additions & 47 deletions app/models/spree/taxon_decorator.rb

This file was deleted.

24 changes: 24 additions & 0 deletions app/models/spree/taxonomy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

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("#{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
50 changes: 50 additions & 0 deletions spec/models/spree/taxon_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# frozen_string_literal: true

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) }
Expand Down Expand Up @@ -46,5 +50,51 @@ 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
expect(taxon.permalink).to eq "ruby-on-rails"
end

it "should support Chinese characters" do
taxon.name = "你好"
taxon.set_permalink
expect(taxon.permalink).to eq 'ni-hao'
end

context "with parent taxon" do
before do
allow(taxon).to receive_messages parent_id: 123
allow(taxon).to receive_messages parent: build(:taxon, permalink: "brands")
end

it "should set permalink correctly when taxon has parent" do
taxon.set_permalink
expect(taxon.permalink).to eq "brands/ruby-on-rails"
end

it "should set permalink correctly with existing permalink present" do
taxon.permalink = "b/rubyonrails"
taxon.set_permalink
expect(taxon.permalink).to eq "brands/rubyonrails"
end

it "should support Chinese characters" do
taxon.name = "我"
taxon.set_permalink
expect(taxon.permalink).to eq "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
expect { taxonomy.root.children.where(name: "Some name").first_or_create }.not_to raise_error
end
end
end
end
19 changes: 19 additions & 0 deletions spec/models/spree/taxonomy_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

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