diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 31d306f123..81a00d4982 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -63,6 +63,7 @@ class Enterprise < ActiveRecord::Base before_save :confirmation_check, if: lambda { email_changed? } + before_validation :initialize_permalink, if: lambda { permalink.nil? } before_validation :ensure_owner_is_manager, if: lambda { owner_id_changed? && !owner_id.nil? } before_validation :set_unused_address_fields after_validation :geocode_address @@ -295,6 +296,21 @@ class Enterprise < ActiveRecord::Base shipping_methods.any? && payment_methods.available.any? end + def self.find_available_permalink(test_permalink) + test_permalink = test_permalink.parameterize + existing = Enterprise.select(:permalink).order(:permalink).where("permalink LIKE ?", "#{test_permalink}%").map(&:permalink) + if existing.empty? + test_permalink + else + used_indices = existing.map do |p| + p.slice!(/^#{test_permalink}/) + p.match(/^\d+$/).to_s.to_i + end.select{ |p| p } + options = (1..existing.length).to_a - used_indices + test_permalink + options.first.to_s + end + end + protected def devise_mailer @@ -370,4 +386,8 @@ class Enterprise < ActiveRecord::Base # If the permalink has errors, reset it to it's original value, so we can update the form self.permalink = permalink_was if permalink_changed? && errors[:permalink].present? end + + def initialize_permalink + self.permalink = Enterprise.find_available_permalink(name) + end end diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index 8b3a8ab443..3e7c6f84d9 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -802,4 +802,42 @@ describe Enterprise do non_producer_sell_none.category.should == :hub_profile end end + + describe "finding and automatically assigning a permalink" do + let(:enterprise) { build(:enterprise, name: "Name To Turn Into A Permalink") } + it "assigns permalink when initialized" do + allow(Enterprise).to receive(:find_available_permalink).and_return("available_permalink") + Enterprise.should_receive(:find_available_permalink).with("Name To Turn Into A Permalink") + expect( + lambda { enterprise.send(:initialize_permalink) } + ).to change{ + enterprise.permalink + }.to( + "available_permalink" + ) + end + + describe "finding a permalink" do + let!(:enterprise1) { create(:enterprise, permalink: "permalink") } + let!(:enterprise2) { create(:enterprise, permalink: "permalink1") } + + it "parameterizes the value provided" do + expect(Enterprise.find_available_permalink("Some Unused Permalink")).to eq "some-unused-permalink" + end + + it "finds and index value based on existing permalinks" do + expect(Enterprise.find_available_permalink("permalink")).to eq "permalink2" + end + + it "ignores permalinks with characters after the index value" do + create(:enterprise, permalink: "permalink2xxx") + expect(Enterprise.find_available_permalink("permalink")).to eq "permalink2" + end + + it "finds gaps in the indices of existing permalinks" do + create(:enterprise, permalink: "permalink3") + expect(Enterprise.find_available_permalink("permalink")).to eq "permalink2" + end + end + end end