Skip to content

Commit

Permalink
Make default_locator as configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
heka1024 committed Aug 24, 2024
1 parent e9548a3 commit 5ed7420
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 2 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,28 @@ end
After defining locators as above, URIs like "gid://foo/Person/1" and "gid://bar/Person/1" will now use the foo block locator and `BarLocator` respectively.
Other apps will still keep using the default locator.

### Custom Default Locator

A custom default locator can be set for an app by calling `GlobalID::Locator.default_locator=` and providing a default locator to use for that app.

```ruby
class MyCustomLocator < UnscopedLocator
def locate(gid, options = {})
ActiveRecord::Base.connected_to(role: :reading) do
super(gid, options)
end
end

def locate_many(gids, options = {})
ActiveRecord::Base.connected_to(role: :reading) do
super(gids, options)
end
end
end

GlobalID::Locator.default_locator = MyCustomLocator.new
```

## Contributing to GlobalID

GlobalID is work of many contributors. You're encouraged to submit pull requests, propose
Expand Down
4 changes: 4 additions & 0 deletions lib/global_id/global_id.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def app=(app)
@app = URI::GID.validate_app(app)
end

def default_locator(default_locator)
Locator.default_locator = default_locator
end

private
def parse_encoded_gid(gid, options)
new(Base64.urlsafe_decode64(gid), options) rescue nil
Expand Down
8 changes: 6 additions & 2 deletions lib/global_id/locator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ module Locator
class InvalidModelIdError < StandardError; end

class << self
# The default locator used when no app-specific locator is found.
attr_accessor :default_locator

# Takes either a GlobalID or a string that can be turned into a GlobalID
#
# Options:
Expand Down Expand Up @@ -134,7 +137,7 @@ def use(app, locator = nil, &locator_block)

private
def locator_for(gid)
@locators.fetch(normalize_app(gid.app)) { DEFAULT_LOCATOR }
@locators.fetch(normalize_app(gid.app)) { default_locator }
end

def find_allowed?(model_class, only = nil)
Expand Down Expand Up @@ -223,7 +226,8 @@ def unscoped(model_class)
end
end
end
DEFAULT_LOCATOR = UnscopedLocator.new

self.default_locator = UnscopedLocator.new

class BlockLocator
def initialize(block)
Expand Down
19 changes: 19 additions & 0 deletions test/cases/global_locator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -386,13 +386,32 @@ def locate_many(gids, options = {}); gids.map(&:model_id); end
assert_equal 2, found.length
end

test "can set default_locator" do
class MyLocator
def locate(gid)
:my_locator
end
end

with_default_locator(MyLocator.new) do
assert_equal :my_locator, GlobalID::Locator.locate('gid://app/Person/1')
end
end

private
def with_app(app)
old_app, GlobalID.app = GlobalID.app, app
yield
ensure
GlobalID.app = old_app
end

def with_default_locator(default_locator)
old_locator, GlobalID::Locator.default_locator = GlobalID::Locator.default_locator, default_locator
yield
ensure
GlobalID::Locator.default_locator = old_locator
end
end

class ScopedRecordLocatingTest < ActiveSupport::TestCase
Expand Down

0 comments on commit 5ed7420

Please sign in to comment.