diff --git a/lib/global_id/identification.rb b/lib/global_id/identification.rb index 759250c..6698607 100644 --- a/lib/global_id/identification.rb +++ b/lib/global_id/identification.rb @@ -116,5 +116,47 @@ 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)) # => #> + # If the object is a string or an integer, it will build a GlobalID using that object. + # Person.build_global_id(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) + + return GlobalID.create(new(id: obj), options) + end + + # Build a Signed Global ID from the given object. + # + # If the object responds to `to_signed_global_id` it will return the result of that call. + # Person.build_signed_global_id(Person.find(1)) # => + # If the object is a string or an integer, it will build a GlobalID using that object. + # Person.build_signed_global_id(1) # => + # If the object is not a string or an integer, it will raise an ArgumentError. + # Person.build_signed_global_id(Person) # => ArgumentError: Can't build a Signed Global ID for Class + # + # An app is required to create a SignedGlobalID. Pass the :app option or set the default GlobalID.app. + def build_signed_global_id(obj, options = {}) + return obj.to_signed_global_id(options) if obj.respond_to?(:to_signed_global_id) + raise ArgumentError, "Can't build a Signed Global ID for #{obj.class}" unless obj.is_a?(String) || obj.is_a?(Integer) + + SignedGlobalID.create(new(id: obj), options) + end + end end end diff --git a/test/cases/global_identification_test.rb b/test/cases/global_identification_test.rb index 86f51d9..f76527b 100644 --- a/test/cases/global_identification_test.rb +++ b/test/cases/global_identification_test.rb @@ -8,26 +8,41 @@ 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 assert_equal SignedGlobalID.create(@model), @model.to_signed_global_id assert_equal SignedGlobalID.create(@model), @model.to_sgid + assert_equal PersonModel.build_signed_global_id(@model), @model.to_sgid + assert_equal PersonModel.build_signed_global_id(1), @model.to_signed_global_id end test 'creates a signed Global ID with purpose ' do assert_equal SignedGlobalID.create(@model, for: 'login'), @model.to_signed_global_id(for: 'login') assert_equal SignedGlobalID.create(@model, for: 'login'), @model.to_sgid(for: 'login') + assert_equal PersonModel.build_signed_global_id(@model, for: 'login'), @model.to_sgid(for: 'login') + assert_equal PersonModel.build_signed_global_id(1, for: 'login'), @model.to_signed_global_id(for: 'login') end test 'creates a signed Global ID with custom params' do assert_equal SignedGlobalID.create(@model, some: 'param'), @model.to_signed_global_id(some: 'param') assert_equal SignedGlobalID.create(@model, some: 'param'), @model.to_sgid(some: 'param') + assert_equal PersonModel.build_signed_global_id(@model, some: 'param'), @model.to_sgid(some: 'param') + assert_equal PersonModel.build_signed_global_id(1, some: 'param'), @model.to_signed_global_id(some: 'param') + end + + test "doesn't create a Global ID if ID is not valid" do + assert_raises(ArgumentError) { PersonModel.build_global_id(PersonModel) } + assert_raises(ArgumentError) { PersonModel.build_signed_global_id(PersonModel) } end test 'dup should clear memoized to_global_id' do