diff --git a/app/models/classification.rb b/app/models/classification.rb index 6a5464eca867..747c0b609fc1 100644 --- a/app/models/classification.rb +++ b/app/models/classification.rb @@ -24,13 +24,14 @@ class Classification < ApplicationRecord validates :syntax, :inclusion => {:in => %w( string integer boolean ), :message => "should be one of 'string', 'integer' or 'boolean'"} + before_validation :nil_parent scope :visible, -> { where(:show => true) } scope :read_only, -> { where(:read_only => true) } scope :writeable, -> { where(:read_only => false) } - scope :is_category, -> { where(:parent_id => 0) } - scope :is_entry, -> { where.not(:parent_id => 0) } + scope :is_category, -> { where(:parent_id => nil) } + scope :is_entry, -> { where.not(:parent_id => nil) } scope :with_writable_parents, -> { includes(:parent).where(:parents_classifications => { :read_only => false}) } @@ -196,7 +197,7 @@ def self.get_tags_from_object(obj) end def self.create_category!(options) - self.create!(options.merge(:parent_id => 0)) + self.create!(options.merge(:parent_id => nil)) end def self.categories(region_id = my_region_number, ns = DEFAULT_NAMESPACE) @@ -306,7 +307,7 @@ def to_tag end def category? - parent_id == 0 + parent_id.nil? end def category @@ -327,11 +328,13 @@ def find_entry_by_name(name, region_id = my_region_number) self.class.find_by_name(name, region_id, ns, self) end - def self.find_by_name(name, region_id = my_region_number, ns = DEFAULT_NAMESPACE, parent_id = 0) + # @param parent_id [Integer|Parent] node for the parent. This is only passed in for find_entry_by_name + def self.find_by_name(name, region_id = my_region_number, ns = DEFAULT_NAMESPACE, parent_id = nil) find_by_names([name], region_id, ns, parent_id).first end - def self.find_by_names(names, region_id = my_region_number, ns = DEFAULT_NAMESPACE, parent_id = 0) + # @param parent_id [Integer|Parent] node for the parent. This is only passed in for find_entry_by_name + def self.find_by_names(names, region_id = my_region_number, ns = DEFAULT_NAMESPACE, parent_id = nil) tag_names = names.map { |name| name2tag(name, parent_id, ns) } # NOTE: tags is a subselect - not an array of ids tags = Tag.in_region(region_id).where(:name => tag_names).select(:id) @@ -395,7 +398,7 @@ def self.import_from_hash(classification, parent = nil) stats = {"categories" => 0, "entries" => 0} - if classification["parent_id"] == 0 # category + if parent.nil? cat = find_by_name(classification["name"]) if cat _log.info("Skipping Classification (already in DB): Category: name=[#{classification["name"]}]") @@ -451,9 +454,6 @@ def self.seed category.save! add_entries_from_hash(category, c[:entries]) end - - # Fix categories that have a nill parent_id - where(:parent_id => nil).update_all(:parent_id => 0) end def self.sanitize_name(name) @@ -492,8 +492,8 @@ def validate_format_of_name end end - def self.name2tag(name, parent_id = 0, ns = DEFAULT_NAMESPACE) - if parent_id == 0 + def self.name2tag(name, parent_id = nil, ns = DEFAULT_NAMESPACE) + if parent_id == 0 || parent_id.nil? File.join(ns, name) else c = parent_id.kind_of?(Classification) ? parent_id : Classification.find(parent_id) @@ -523,12 +523,12 @@ def self.tag2human(tag) private_class_method :tag2human def find_tag - tag_name = Classification.name2tag(name, parent_id, ns) + tag_name = Classification.name2tag(name, parent, ns) Tag.in_region(region_id).find_by(:name => tag_name) end def save_tag - tag_name = Classification.name2tag(name, parent_id, ns) + tag_name = Classification.name2tag(name, parent, ns) self.tag = Tag.in_region(region_id).find_or_create_by(:name => tag_name) end @@ -559,4 +559,8 @@ def delete_tags_and_entries delete_tag_and_taggings end + + def nil_parent + self.parent_id = nil if parent_id == 0 + end end diff --git a/app/models/vm_or_template.rb b/app/models/vm_or_template.rb index 2f8a3ae70203..f49fcb025edb 100644 --- a/app/models/vm_or_template.rb +++ b/app/models/vm_or_template.rb @@ -1383,7 +1383,6 @@ def self.folder_category(folder_type) cat = Classification.new( :name => cat_name, :description => "Parent Folder Path (#{folder_type == :blue ? "VMs & Templates" : "Hosts & Clusters"})", - :parent_id => 0, :single_value => true, :read_only => true ) diff --git a/db/fixtures/classifications.yml b/db/fixtures/classifications.yml index fffaeec05a15..1e8ededb235d 100644 --- a/db/fixtures/classifications.yml +++ b/db/fixtures/classifications.yml @@ -34,7 +34,6 @@ :show: true :name: location :example_text: The geographic location of the resource, such as New York, Chicago, or London. - :parent_id: 0 :default: true :single_value: "1" - :description: Workload @@ -107,7 +106,6 @@ :show: true :name: function :example_text: The workloads a resource provides, such as Web Server, Database, or Firewall. - :parent_id: 0 :default: true :single_value: "0" - :description: Owner @@ -138,7 +136,6 @@ :show: true :name: owner :example_text: The individual or group that owns the resource. - :parent_id: 0 :default: true :single_value: "1" - :description: Environment @@ -183,7 +180,6 @@ :show: true :name: environment :example_text: The resource environment, such as Development, QA, Test, or Production - :parent_id: 0 :default: true :single_value: "1" - :description: User roles @@ -242,7 +238,6 @@ :show: true :name: role :example_text: - :parent_id: 0 :default: true :single_value: "1" :ns: /managed/user @@ -274,7 +269,6 @@ :show: true :name: service_level :example_text: The level of service associated with this resource. - :parent_id: 0 :default: true :single_value: "1" - :description: Customer @@ -285,7 +279,6 @@ :show: true :name: customer :example_text: The name of the customer associated with this resource. - :parent_id: 0 :default: true :single_value: t - :description: Line of Business @@ -296,7 +289,6 @@ :show: true :name: lob :example_text: The Line of Business the resource is assigned to, such as Retail, Trading, or Manufacturing. - :parent_id: 0 :default: true :single_value: "0" - :description: Department @@ -418,7 +410,6 @@ :show: true :name: department :example_text: The department the resource is assigned to, such as HR, Accounting, or Sales. - :parent_id: 0 :default: true :single_value: "0" - :description: Cost Center @@ -442,7 +433,6 @@ :show: true :name: cc :example_text: Cost Center - :parent_id: 0 :default: true :single_value: "1" - :description: Network Location @@ -473,7 +463,6 @@ :show: true :name: network_location :example_text: The network location the resource is to be used, such as DMZ, Internal network or Cloud - :parent_id: 0 :default: true :single_value: "1" - :description: Exclusions @@ -497,7 +486,6 @@ :show: true :name: exclusions :example_text: Operations that the resource may be excluded from, such as Analysis or Cloning. - :parent_id: 0 :default: true :single_value: "0" - :description: Provisioning Scope @@ -521,7 +509,6 @@ :show: true :name: prov_scope :example_text: Provisioning Scope - :parent_id: 0 :default: true :single_value: "0" - :description: EVM Operations @@ -552,7 +539,6 @@ :show: true :name: operations :example_text: Operations - :parent_id: 0 :default: true :single_value: "1" - :description: Quota - Max CPUs @@ -632,7 +618,6 @@ :show: true :name: quota_max_cpu :example_text: Maximum number of CPUs allowed by Quota - :parent_id: 0 :default: true :single_value: "1" - :description: Auto Approve - Max CPU @@ -677,7 +662,6 @@ :show: true :name: prov_max_cpu :example_text: Maximum number of CPUs allowed by Auto Approval - :parent_id: 0 :default: true :single_value: "1" - :description: Auto Approve - Max VM @@ -722,7 +706,6 @@ :show: true :name: prov_max_vm :example_text: Maximum number of VMs allowed by Auto Approval - :parent_id: 0 :default: true :single_value: "1" - :description: Quota - Max Memory @@ -788,7 +771,6 @@ :show: true :name: quota_max_memory :example_text: Maximum Memory allowed by Quota (GB) - :parent_id: 0 :default: true :single_value: "1" - :description: Auto Approve - Max Memory @@ -826,7 +808,6 @@ :show: true :name: prov_max_memory :example_text: Maximum Memory allowed by Auto Approval (GB) - :parent_id: 0 :default: true :single_value: "1" - :description: Quota - Max Storage @@ -885,7 +866,6 @@ :show: true :name: quota_max_storage :example_text: Maximum Storage allowed by Quota (GB) - :parent_id: 0 :default: true :single_value: "1" - :description: Auto Approve - Max Retirement Days @@ -923,7 +903,6 @@ :show: true :name: prov_max_retirement_days :example_text: Maximum Days for Retirement allowed by Auto Approval - :parent_id: 0 :default: true :single_value: "1" - :description: LifeCycle @@ -940,7 +919,6 @@ :show: true :name: lifecycle :example_text: LifeCycle Options - :parent_id: 0 :default: true :single_value: "1" - :description: Migration Group @@ -971,7 +949,6 @@ :show: true :name: migration_group :example_text: Group of VMs prepared for migration. - :parent_id: 0 :default: true :single_value: "1" - :description: Network Mapping @@ -988,7 +965,6 @@ :show: true :name: network_mapping :example_text: Mapping between source network(s) and a destination network for migration. - :parent_id: 0 :default: true :single_value: "1" - :description: Storage Mapping @@ -1019,7 +995,6 @@ :show: true :name: storage_mapping :example_text: Mapping between source storage(s) and a destination storage for migration. - :parent_id: 0 :default: true :single_value: "1" - :description: V2V - Transformation Host @@ -1043,7 +1018,6 @@ :show: true :name: v2v_transformation_host :example_text: Transformation Host role enabled for V2V. - :parent_id: 0 :default: true :single_value: "1" - :description: V2V - Transformation Method @@ -1067,7 +1041,6 @@ :show: true :name: v2v_transformation_method :example_text: Transformation methods supported for V2V. - :parent_id: 0 :default: true :single_value: "0" - :description: Transformation Status @@ -1084,6 +1057,5 @@ :show: true :name: transformation_status :example_text: VM has been migrated. - :parent_id: 0 :default: true :single_value: "1" diff --git a/spec/factories/categories.rb b/spec/factories/categories.rb index f00c85a358b2..977257f73117 100644 --- a/spec/factories/categories.rb +++ b/spec/factories/categories.rb @@ -2,6 +2,5 @@ factory(:category) do sequence(:name) { |n| "category_#{seq_padded_for_sorting(n)}" } sequence(:description) { |n| "category #{seq_padded_for_sorting(n)}" } - parent_id 0 end end diff --git a/spec/factories/classification.rb b/spec/factories/classification.rb index b18d2e52f720..b2baa336c0db 100644 --- a/spec/factories/classification.rb +++ b/spec/factories/classification.rb @@ -2,7 +2,6 @@ factory :classification do sequence(:name) { |n| "category_#{seq_padded_for_sorting(n)}" } sequence(:description) { |n| "category #{seq_padded_for_sorting(n)}" } - parent_id 0 end factory :classification_tag, :class => :Classification do diff --git a/spec/lib/task_helpers/exports/tags_spec.rb b/spec/lib/task_helpers/exports/tags_spec.rb index 4ec8862c308e..0d859c9bc4e3 100644 --- a/spec/lib/task_helpers/exports/tags_spec.rb +++ b/spec/lib/task_helpers/exports/tags_spec.rb @@ -11,7 +11,6 @@ "syntax" => "string", "single_value" => false, "example_text" => nil, - "parent_id" => 0, "show" => true, "default" => nil, "perf_by_tag" => nil, @@ -45,7 +44,6 @@ "syntax" => "string", "single_value" => false, "example_text" => nil, - "parent_id" => 0, "show" => true, "default" => true, "perf_by_tag" => nil, @@ -69,7 +67,6 @@ "syntax" => "string", "single_value" => false, "example_text" => nil, - "parent_id" => 0, "show" => true, "default" => true, "perf_by_tag" => nil, diff --git a/spec/lib/task_helpers/imports/data/tags/Import_Test.yaml b/spec/lib/task_helpers/imports/data/tags/Import_Test.yaml index ca01193df845..a34723c19439 100644 --- a/spec/lib/task_helpers/imports/data/tags/Import_Test.yaml +++ b/spec/lib/task_helpers/imports/data/tags/Import_Test.yaml @@ -5,7 +5,6 @@ syntax: string single_value: true example_text: Tag Import Test - parent_id: 0 show: true default: perf_by_tag: false diff --git a/spec/lib/task_helpers/imports/data/tags/Location.yaml b/spec/lib/task_helpers/imports/data/tags/Location.yaml index 289f67fbdd41..9abf5ac5ba06 100644 --- a/spec/lib/task_helpers/imports/data/tags/Location.yaml +++ b/spec/lib/task_helpers/imports/data/tags/Location.yaml @@ -6,7 +6,6 @@ single_value: true example_text: The geographic location of the resource, such as New York, Chicago, or London. - parent_id: 0 show: true default: true perf_by_tag: diff --git a/spec/lib/task_helpers/imports/data/tags/Tag_Test_Fail_Cat.yml b/spec/lib/task_helpers/imports/data/tags/Tag_Test_Fail_Cat.yml index b1fc64287a74..d7d251b052ec 100644 --- a/spec/lib/task_helpers/imports/data/tags/Tag_Test_Fail_Cat.yml +++ b/spec/lib/task_helpers/imports/data/tags/Tag_Test_Fail_Cat.yml @@ -5,7 +5,6 @@ syntax: string single_value: true example_text: Brant Test - parent_id: 0 show: true default: perf_by_tag: false diff --git a/spec/lib/task_helpers/imports/data/tags/Tag_Test_Fail_Entry.yml b/spec/lib/task_helpers/imports/data/tags/Tag_Test_Fail_Entry.yml index ce1fca2ce456..fc1670ac2c54 100644 --- a/spec/lib/task_helpers/imports/data/tags/Tag_Test_Fail_Entry.yml +++ b/spec/lib/task_helpers/imports/data/tags/Tag_Test_Fail_Entry.yml @@ -5,7 +5,6 @@ syntax: string single_value: true example_text: Brant Test - parent_id: 0 show: true default: perf_by_tag: false diff --git a/spec/models/classification_spec.rb b/spec/models/classification_spec.rb index 01aa59dcd4b0..dbe1287a2b73 100644 --- a/spec/models/classification_spec.rb +++ b/spec/models/classification_spec.rb @@ -192,7 +192,7 @@ 'My_Name_is...', '123456789_123456789_123456789_123456789_123456789_1' ].each do |name| - cat = Classification.new(:name => name, :parent_id => 0) + cat = Classification.new(:name => name) expect(cat).to_not be_valid expect(cat.errors[:name].size).to eq(1) @@ -206,7 +206,7 @@ '123456789_123456789_123456789_123456789_123456789_1' ].each do |name| good_name = Classification.sanitize_name(name) - cat = Classification.new(:name => good_name, :description => name, :parent_id => 0) + cat = Classification.new(:name => good_name, :description => name) expect(cat).to be_valid end end @@ -408,7 +408,6 @@ :read_only => "0", :syntax => "string", :show => true, - :parent_id => 0, :default => true, :single_value => "1", :entries => [{:description => "Cost Center 001", :name => "001"}, @@ -563,6 +562,16 @@ end end + describe '.create_category!' do + it "is a category" do + c1 = Classification.create_category!(:name => 'a', :description => 'a') + c2 = Classification.create_category!(:name => 'b', :description => 'b', :parent => c1) + + expect(c1).to be_category + expect(c2).to be_category + end + end + def all_tagged_with(target, all, category = nil) tagged_with(target, :all => all, :cat => category) end