Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GlobalId::Identification::build_global_id #186

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions lib/global_id/identification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,35 @@ def to_signed_global_id(options = {})
def to_sgid_param(options = {})
to_signed_global_id(options).to_param
end

class << self
def included(base)
base.extend(ClassMethods)
end
end

module ClassMethods
# Build a Global ID from the given object.
#
# If the object responds to `to_global_id` it will return the result of that call.
# Person.build_global_id(Person.find(1)) # => #<GlobalID:0x000000012b7dcea0 @uri=#<URI::GID gid://app/Person/1>>
# If the object is a string or an integer, it will build a GlobalID using that object.
# Person.build_global_id(1) # => #<GlobalID:0x000000012b7dcea0 @uri=#<URI::GID gid://app/Person/1>>
# If the object is not a string or an integer, it will raise an ArgumentError.
# Person.build_global_id(Person) # => ArgumentError: Can't build a Global ID for Class
#
# An app is required to create a GlobalID. Pass the :app option or set the default GlobalID.app.

def build_global_id(obj, options = {})
return obj.to_global_id(options) if obj.respond_to?(:to_global_id)
raise ArgumentError, "Can't build a Global ID for #{obj.class}" unless obj.is_a?(String) || obj.is_a?(Integer)

unless (app = options.fetch(:app) { GlobalID.app })
raise ArgumentError, "An app is required to create a GlobalID. Pass the :app option or set the default GlobalID.app."
end

GlobalID.new(URI::GID.build(app: app, model_name: name, model_id: obj, params: options.except(:app, :verifier, :for)))
end
end
end
end
8 changes: 8 additions & 0 deletions test/cases/global_identification_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ class GlobalIdentificationTest < ActiveSupport::TestCase
test 'creates a Global ID from self' do
assert_equal GlobalID.create(@model), @model.to_global_id
assert_equal GlobalID.create(@model), @model.to_gid
assert_equal PersonModel.build_global_id(@model), @model.to_gid
assert_equal PersonModel.build_global_id(1), @model.to_global_id
end

test 'creates a Global ID with custom params' do
assert_equal GlobalID.create(@model, some: 'param'), @model.to_global_id(some: 'param')
assert_equal GlobalID.create(@model, some: 'param'), @model.to_gid(some: 'param')
assert_equal PersonModel.build_global_id(@model, some: 'param'), @model.to_gid(some: 'param')
assert_equal PersonModel.build_global_id(1, some: 'param'), @model.to_global_id(some: 'param')
end

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

test "doesn't create a Global ID if ID is not valid" do
assert_raises(ArgumentError) { PersonModel.build_global_id(PersonModel) }
end

test 'dup should clear memoized to_global_id' do
global_id = @model.to_global_id
dup_model = @model.dup
Expand Down
Loading