Commit 4d517ac1 authored by Alex Kalderimis's avatar Alex Kalderimis

Enhance Global-ID handling

This splits out GID parsing, and adds support for asserting expected
types.
parent 7b2baef3
...@@ -58,12 +58,26 @@ class GitlabSchema < GraphQL::Schema ...@@ -58,12 +58,26 @@ class GitlabSchema < GraphQL::Schema
end end
def object_from_id(global_id, ctx = {}) def object_from_id(global_id, ctx = {})
gid = parse_gid(global_id, ctx)
find_by_gid(gid)
end
def find_by_gid(gid)
if gid.model_class < ApplicationRecord
Gitlab::Graphql::Loaders::BatchModelLoader.new(gid.model_class, gid.model_id).find
elsif gid.model_class.respond_to?(:lazy_find)
gid.model_class.lazy_find(gid.model_id)
else
gid.find
end
end
def parse_gid(global_id, ctx = {})
expected_type = ctx[:expected_type] expected_type = ctx[:expected_type]
gid = GlobalID.parse(global_id) gid = GlobalID.parse(global_id)
unless gid raise Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid GitLab id." unless gid
raise Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid GitLab id."
end
if expected_type && !gid.model_class.ancestors.include?(expected_type) if expected_type && !gid.model_class.ancestors.include?(expected_type)
vars = { global_id: global_id, expected_type: expected_type } vars = { global_id: global_id, expected_type: expected_type }
...@@ -71,13 +85,7 @@ class GitlabSchema < GraphQL::Schema ...@@ -71,13 +85,7 @@ class GitlabSchema < GraphQL::Schema
raise Gitlab::Graphql::Errors::ArgumentError, msg raise Gitlab::Graphql::Errors::ArgumentError, msg
end end
if gid.model_class < ApplicationRecord gid
Gitlab::Graphql::Loaders::BatchModelLoader.new(gid.model_class, gid.model_id).find
elsif gid.model_class.respond_to?(:lazy_find)
gid.model_class.lazy_find(gid.model_id)
else
gid.find
end
end end
private private
......
...@@ -124,14 +124,26 @@ describe GitlabSchema do ...@@ -124,14 +124,26 @@ describe GitlabSchema do
describe '.object_from_id' do describe '.object_from_id' do
context 'for subclasses of `ApplicationRecord`' do context 'for subclasses of `ApplicationRecord`' do
it 'returns the correct record' do let_it_be(:user) { create(:user) }
user = create(:user)
it 'returns the correct record' do
result = described_class.object_from_id(user.to_global_id.to_s) result = described_class.object_from_id(user.to_global_id.to_s)
expect(result.sync).to eq(user) expect(result.sync).to eq(user)
end end
it 'returns the correct record, of the expected type' do
result = described_class.object_from_id(user.to_global_id.to_s, expected_type: ::User)
expect(result.sync).to eq(user)
end
it 'fails if the type does not match' do
expect do
described_class.object_from_id(user.to_global_id.to_s, expected_type: ::Project)
end.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
end
it 'batchloads the queries' do it 'batchloads the queries' do
user1 = create(:user) user1 = create(:user)
user2 = create(:user) user2 = create(:user)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment