Skip to content

Commit 8666784

Browse files
authored
Merge pull request #179 from heka1024/configurable-base-locator
Make `DEFAULT_LOCATOR` Configurable
2 parents 460279d + 5ed7420 commit 8666784

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,28 @@ end
210210
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.
211211
Other apps will still keep using the default locator.
212212

213+
### Custom Default Locator
214+
215+
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.
216+
217+
```ruby
218+
class MyCustomLocator < UnscopedLocator
219+
def locate(gid, options = {})
220+
ActiveRecord::Base.connected_to(role: :reading) do
221+
super(gid, options)
222+
end
223+
end
224+
225+
def locate_many(gids, options = {})
226+
ActiveRecord::Base.connected_to(role: :reading) do
227+
super(gids, options)
228+
end
229+
end
230+
end
231+
232+
GlobalID::Locator.default_locator = MyCustomLocator.new
233+
```
234+
213235
## Contributing to GlobalID
214236

215237
GlobalID is work of many contributors. You're encouraged to submit pull requests, propose

lib/global_id/global_id.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def app=(app)
3232
@app = URI::GID.validate_app(app)
3333
end
3434

35+
def default_locator(default_locator)
36+
Locator.default_locator = default_locator
37+
end
38+
3539
private
3640
def parse_encoded_gid(gid, options)
3741
new(Base64.urlsafe_decode64(gid), options) rescue nil

lib/global_id/locator.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ module Locator
55
class InvalidModelIdError < StandardError; end
66

77
class << self
8+
# The default locator used when no app-specific locator is found.
9+
attr_accessor :default_locator
10+
811
# Takes either a GlobalID or a string that can be turned into a GlobalID
912
#
1013
# Options:
@@ -134,7 +137,7 @@ def use(app, locator = nil, &locator_block)
134137

135138
private
136139
def locator_for(gid)
137-
@locators.fetch(normalize_app(gid.app)) { DEFAULT_LOCATOR }
140+
@locators.fetch(normalize_app(gid.app)) { default_locator }
138141
end
139142

140143
def find_allowed?(model_class, only = nil)
@@ -223,7 +226,8 @@ def unscoped(model_class)
223226
end
224227
end
225228
end
226-
DEFAULT_LOCATOR = UnscopedLocator.new
229+
230+
self.default_locator = UnscopedLocator.new
227231

228232
class BlockLocator
229233
def initialize(block)

test/cases/global_locator_test.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,32 @@ def locate_many(gids, options = {}); gids.map(&:model_id); end
386386
assert_equal 2, found.length
387387
end
388388

389+
test "can set default_locator" do
390+
class MyLocator
391+
def locate(gid)
392+
:my_locator
393+
end
394+
end
395+
396+
with_default_locator(MyLocator.new) do
397+
assert_equal :my_locator, GlobalID::Locator.locate('gid://app/Person/1')
398+
end
399+
end
400+
389401
private
390402
def with_app(app)
391403
old_app, GlobalID.app = GlobalID.app, app
392404
yield
393405
ensure
394406
GlobalID.app = old_app
395407
end
408+
409+
def with_default_locator(default_locator)
410+
old_locator, GlobalID::Locator.default_locator = GlobalID::Locator.default_locator, default_locator
411+
yield
412+
ensure
413+
GlobalID::Locator.default_locator = old_locator
414+
end
396415
end
397416

398417
class ScopedRecordLocatingTest < ActiveSupport::TestCase

0 commit comments

Comments
 (0)