From 6e8f3fab6c2bfbdc81586183051db31183b96b32 Mon Sep 17 00:00:00 2001 From: ziggy Date: Tue, 28 Mar 2017 14:02:43 -0400 Subject: [PATCH] add remove_extension & remove_extensions_by_def_ids --- app/models/entity.rb | 28 ++++++++++-- spec/helpers/entities_helper_spec.rb | 2 +- spec/models/entity_spec.rb | 64 ++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/app/models/entity.rb b/app/models/entity.rb index ed51fd8ab..e9f22a744 100644 --- a/app/models/entity.rb +++ b/app/models/entity.rb @@ -149,12 +149,28 @@ def extension_names extension_ids.collect { |id| self.class.all_extension_names[id] } end + # Adds a new extension. Creates ExtensionRecord and extension model if required + # Call with the name of the extenion model or with the definition id + # It will not create duplicates and is safe to run multiple times with with the same value + # Example: Entity.find(123).add_extension('Business') def add_extension(name_or_id, fields = {}) name = name_or_id_to_name(name_or_id) fields[:entity] = self - name.constantize.create(fields) if self.class.all_extension_names_with_fields.include?(name) && name.constantize.where(entity_id: id).count.zero? + name.constantize.create(fields) if extension_with_fields?(name) && name.constantize.where(entity_id: id).count.zero? def_id = ExtensionDefinition.find_by_name(name).id ExtensionRecord.find_or_create_by(entity_id: id, definition_id: def_id) + self + end + + # Removes existing ExtensionRecord and associated model + def remove_extension(name_or_id) + name = name_or_id_to_name(name_or_id) + # This func cannot be used to remove a primary extension + raise ArgumentError if %w(None Org Person).include?(name) + def_id = self.class.all_extension_names.index(name) + extension_records.find_by_definition_id(def_id).try(:destroy) + send(name.underscore).try(:destroy) if extension_with_fields?(name) + self end # Create new extension by definition ids @@ -164,8 +180,8 @@ def add_extensions_by_def_ids(ids) end # Removes extensions by definition id - def remove_extensions_by_def_id(id) - + def remove_extensions_by_def_ids(ids) + ids.each { |def_id| remove_extension(def_id) } end def self.with_exts(exts) @@ -646,7 +662,7 @@ def name_or_id_to_name(name_or_id) case name_or_id when String return name_or_id if self.class.all_extension_names.include?(name_or_id) - raise ArgumentError, "there are no extensions associated with name #{name_or_id}" + raise ArgumentError, "there are no extensions associated with name: #{name_or_id}" when Integer name = self.class.all_extension_names[name_or_id] return name unless name.nil? @@ -656,4 +672,8 @@ def name_or_id_to_name(name_or_id) end end + def extension_with_fields?(name) + self.class.all_extension_names_with_fields.include?(name) + end + end diff --git a/spec/helpers/entities_helper_spec.rb b/spec/helpers/entities_helper_spec.rb index b82d70bc5..ecead4f47 100644 --- a/spec/helpers/entities_helper_spec.rb +++ b/spec/helpers/entities_helper_spec.rb @@ -32,7 +32,7 @@ it 'contains one checkbox if org has an extension' do org = create(:org) - org.add_extension('business') + org.add_extension('Business') expect(helper.checkboxes(org).reduce(:+).scan('glyphicon-check').count).to eq 1 expect(helper.checkboxes(org).reduce(:+).scan('glyphicon-unchecked').count).to eq 24 end diff --git a/spec/models/entity_spec.rb b/spec/models/entity_spec.rb index 8f848b625..740275641 100644 --- a/spec/models/entity_spec.rb +++ b/spec/models/entity_spec.rb @@ -170,7 +170,6 @@ def without_ids(array) expect(create_school.extension_names). to eql ['Org', 'School'] end end - describe 'name_or_id_to_name' do it 'converts def id to name' do @@ -195,11 +194,48 @@ def without_ids(array) end describe 'remove_extension' do - - end + it 'removes extension records' do + org = create(:org) + expect(org.extension_records.count).to eq 1 + org.add_extension('IndustryTrade') + expect(org.extension_records.count).to eq 2 + org.remove_extension('IndustryTrade') + expect(org.extension_records.count).to eq 1 + end + + it 'removes extension records and their models' do + person = create(:person) + expect(person.extension_records.count).to eq 1 + expect(person.political_candidate).to be nil + person.add_extension('PoliticalCandidate') + expect(person.extension_records.count).to eq 2 + expect(person.political_candidate).to be_a PoliticalCandidate + person.remove_extension('PoliticalCandidate') + expect(person.extension_records.count).to eq 1 + expect(person.reload.political_candidate).to be nil + end + + it 'can be run multiple times' do + person = create(:person) + expect { person.add_extension('PoliticalCandidate') }.to change { PoliticalCandidate.count }.by(1) + expect { person.add_extension('PoliticalCandidate') }.not_to change { PoliticalCandidate.count } + expect { person.remove_extension('PoliticalCandidate') }.to change { PoliticalCandidate.count }.by(-1) + expect { person.remove_extension('PoliticalCandidate') }.not_to change { PoliticalCandidate.count } + end + + it 'nothing happens if the extension does not exist' do + org = create(:org) + expect { org.remove_extension('LaborUnion') }.not_to change { ExtensionRecord.count } + expect { org.remove_extension('Business') }.not_to change { Business.count } + end + it 'prevents you from removing primary extensions' do + expect { build(:org).remove_extension('Org') }.to raise_error(ArgumentError) + expect { build(:person).remove_extension('Person') }.to raise_error(ArgumentError) + end + end - describe 'add_extensions_by_def_ids' do + describe '#add_extensions_by_def_ids' do it 'creates extension records' do org = create(:org) expect(org.extension_records.count).to eq 1 @@ -220,5 +256,25 @@ def without_ids(array) expect(org.business).to be_a Business end end + + describe '#remove_extensions_by_def_ids' do + before do + @org = create(:org) + @org.add_extension('School') + @org.add_extension('NonProfit') + end + + it 'removes extension records' do + expect { @org.remove_extensions_by_def_ids([7, 10]) }.to change { ExtensionRecord.count }.by(-2) + end + + it 'removes extension model' do + expect { @org.remove_extensions_by_def_ids([7, 10]) }.to change { School.count }.by(-1) + end + + it 'silently ignores extensions that do not exist' do + expect { @org.remove_extensions_by_def_ids([7, 10, 9]) }.to change { ExtensionRecord.count }.by(-2) + end + end end # end Extension Attributes Functions end