diff --git a/app/models/application_record.rb b/app/models/application_record.rb index bdf5c751166..16711bd5530 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -6,6 +6,7 @@ class ApplicationRecord < ActiveRecord::Base include ArRegion include ArLock include ArNestedCountBy + include ArHrefSlug include ToModelHash extend ArTableLock diff --git a/lib/api/collection_config.rb b/lib/api/collection_config.rb index 4a3574adedf..5376530e66c 100644 --- a/lib/api/collection_config.rb +++ b/lib/api/collection_config.rb @@ -73,6 +73,13 @@ def name_for_klass(resource_klass) @cfg.detect { |_, spec| spec[:klass] == resource_klass.name }.try(:first) end + def name_for_subclass(resource_class) + @cfg.detect do |collection, _| + collection_class = klass(collection) + collection_class && (collection_class == resource_class || collection_class.descendants.include?(resource_class)) + end.try(:first) + end + def what_refers_to_feature(product_feature_name) referenced_identifiers[product_feature_name] end diff --git a/lib/api/utils.rb b/lib/api/utils.rb new file mode 100644 index 00000000000..dba4d93fefd --- /dev/null +++ b/lib/api/utils.rb @@ -0,0 +1,9 @@ +module Api + module Utils + def self.build_href_slug(klass, id) + return unless id + collection = Api::CollectionConfig.new.name_for_subclass(klass) + "#{collection}/#{id}" if collection + end + end +end diff --git a/lib/extensions/ar_href_slug.rb b/lib/extensions/ar_href_slug.rb new file mode 100644 index 00000000000..c55a170130c --- /dev/null +++ b/lib/extensions/ar_href_slug.rb @@ -0,0 +1,11 @@ +module ArHrefSlug + extend ActiveSupport::Concern + + included do + virtual_column :href_slug, :type => :string + + def href_slug + Api::Utils.build_href_slug(self.class, id) + end + end +end diff --git a/spec/lib/api/collection_config_spec.rb b/spec/lib/api/collection_config_spec.rb index 42f73a2c2b0..36e71de222d 100644 --- a/spec/lib/api/collection_config_spec.rb +++ b/spec/lib/api/collection_config_spec.rb @@ -8,4 +8,18 @@ expect(subject.name_for_klass(String)).to be_nil end end + + describe "#name_for_subclass" do + it "returns the collection name for classes declared by the API" do + expect(subject.name_for_subclass(Vm)).to eq(:vms) + end + + it "returns the collection name for classes that are accessible via collection_class" do + expect(subject.name_for_subclass(ManageIQ::Providers::Vmware::InfraManager::Vm)).to eq(:vms) + end + + it "returns nil for classes unknown to the API" do + expect(subject.name_for_subclass(String)).to be_nil + end + end end diff --git a/spec/requests/api/querying_spec.rb b/spec/requests/api/querying_spec.rb index 1e10dfc1cda..e84c4bec712 100644 --- a/spec/requests/api/querying_spec.rb +++ b/spec/requests/api/querying_spec.rb @@ -506,7 +506,7 @@ def create_vms_by_name(names) api_basic_authorize collection_action_identifier(:vms, :read, :get) vm = create_vms_by_name(%w(aa)).first - run_get vms_url, :expand => "resources", :attributes => "name,vendor" + run_get vms_url, :expand => "resources", :attributes => "href_slug,name,vendor" expected = { "name" => "vms", @@ -514,10 +514,11 @@ def create_vms_by_name(names) "subcount" => 1, "resources" => [ { - "id" => vm.id, - "href" => a_string_matching(vms_url(vm.id)), - "name" => "aa", - "vendor" => anything + "id" => vm.id, + "href" => a_string_matching(vms_url(vm.id)), + "href_slug" => "vms/#{vm.id}", + "name" => "aa", + "vendor" => anything } ] }