Skip to content

Commit f8764fd

Browse files
committed
GlobalId::Identification::build_global_id
1 parent e9548a3 commit f8764fd

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

lib/global_id/identification.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,35 @@ def to_signed_global_id(options = {})
116116
def to_sgid_param(options = {})
117117
to_signed_global_id(options).to_param
118118
end
119+
120+
class << self
121+
def included(base)
122+
base.extend(ClassMethods)
123+
end
124+
end
125+
126+
module ClassMethods
127+
# Build a Global ID from the given object.
128+
#
129+
# If the object responds to `to_global_id` it will return the result of that call.
130+
# Person.build_global_id(Person.find(1)) # => #<GlobalID:0x000000012b7dcea0 @uri=#<URI::GID gid://app/Person/1>>
131+
# If the object is a string or an integer, it will build a GlobalID using that object.
132+
# Person.build_global_id(1) # => #<GlobalID:0x000000012b7dcea0 @uri=#<URI::GID gid://app/Person/1>>
133+
# If the object is not a string or an integer, it will raise an ArgumentError.
134+
# Person.build_global_id(Person) # => ArgumentError: Can't build a Global ID for Class
135+
#
136+
# An app is required to create a GlobalID. Pass the :app option or set the default GlobalID.app.
137+
138+
def build_global_id(obj, options = {})
139+
return obj.to_global_id(options) if obj.respond_to?(:to_global_id)
140+
raise ArgumentError, "Can't build a Global ID for #{obj.class}" unless obj.is_a?(String) || obj.is_a?(Integer)
141+
142+
unless (app = options.fetch(:app) { GlobalID.app })
143+
raise ArgumentError, "An app is required to create a GlobalID. Pass the :app option or set the default GlobalID.app."
144+
end
145+
146+
GlobalID.new(URI::GID.build(app: app, model_name: name, model_id: obj, params: options.except(:app, :verifier, :for)))
147+
end
148+
end
119149
end
120150
end

test/cases/global_identification_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ class GlobalIdentificationTest < ActiveSupport::TestCase
88
test 'creates a Global ID from self' do
99
assert_equal GlobalID.create(@model), @model.to_global_id
1010
assert_equal GlobalID.create(@model), @model.to_gid
11+
assert_equal PersonModel.build_global_id(@model), @model.to_gid
12+
assert_equal PersonModel.build_global_id(1), @model.to_global_id
1113
end
1214

1315
test 'creates a Global ID with custom params' do
1416
assert_equal GlobalID.create(@model, some: 'param'), @model.to_global_id(some: 'param')
1517
assert_equal GlobalID.create(@model, some: 'param'), @model.to_gid(some: 'param')
18+
assert_equal PersonModel.build_global_id(@model, some: 'param'), @model.to_gid(some: 'param')
19+
assert_equal PersonModel.build_global_id(1, some: 'param'), @model.to_global_id(some: 'param')
1620
end
1721

1822
test 'creates a signed Global ID from self' do
@@ -30,6 +34,10 @@ class GlobalIdentificationTest < ActiveSupport::TestCase
3034
assert_equal SignedGlobalID.create(@model, some: 'param'), @model.to_sgid(some: 'param')
3135
end
3236

37+
test "doesn't create a Global ID if ID is not valid" do
38+
assert_raises(ArgumentError) { PersonModel.build_global_id(PersonModel) }
39+
end
40+
3341
test 'dup should clear memoized to_global_id' do
3442
global_id = @model.to_global_id
3543
dup_model = @model.dup

0 commit comments

Comments
 (0)