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

Apps can hook in their own locator. #15

Merged
merged 1 commit into from
Aug 21, 2014
Merged

Apps can hook in their own locator. #15

merged 1 commit into from
Aug 21, 2014

Conversation

kaspth
Copy link
Contributor

@kaspth kaspth commented Aug 18, 2014

Adds #7.

# end
def use(locator_name, locator = nil)
@locator = locator || Base.new(Proc.new)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The locators are for a specific app, so gid://foo/Model/id would be located using the block above and gid://bar/Other/id would be located using BarLocator.

def use(app, locator = nil, &locator_block)
  raise ArgumentError, 'No locator provided. Pass a block or an object that responds to #locate.' unless locator || locator_block
  @locators[app.to_s.downcase] = locator || BlockLocator.new(&locator_block)
end

@jeremy
Copy link
Member

jeremy commented Aug 18, 2014

Thanks @kaspth! Commented on the link between app and their locators - idea is to be able to bind a locator to an app.

@kaspth
Copy link
Contributor Author

kaspth commented Aug 18, 2014

@jeremy I think I got it now.

assert_equal options[:returns], GlobalID::Locator.locate(gid)
ensure
GlobalID.app = old_app
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new line at the end of the file :trollface:

@kaspth
Copy link
Contributor Author

kaspth commented Aug 18, 2014

Cramped build queue? It's been saying waiting for two hours...

@@ -3,13 +3,60 @@ module Locator
class << self
# Takes either a GlobalID or a string that can be turned into a GlobalID
def locate(gid)
GlobalID.find gid
@locators[GlobalID.app].locate gid
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than the current default app that's used for creating new gids, we need to use the app that's in the URI we're parsing: gid://<app here>/model/id. That means we'll need to parse the gid first and use @locators[gid.app] to do the find.

That suggests that GlobalID#find is what really needs to change. Rather than hardcoding model_class.find(model_id) it needs to ask for the locator for its app, then ask the locator to do the find. The default locator would be an ActiveRecordFinder instance that does def locate(gid) gid.model_class.find gid.model_id end 😁

@seuros
Copy link
Member

seuros commented Aug 18, 2014

@kaspth you PR need be rebased
This pull request contains merge conflicts that must be resolved.

@kaspth
Copy link
Contributor Author

kaspth commented Aug 18, 2014

Sorry, guys. I'm too sleepy to finish this now. This is as far as I will come today.

@jeremy
Copy link
Member

jeremy commented Aug 18, 2014

❤️

On Mon, Aug 18, 2014 at 1:11 PM, Kasper Timm Hansen <
notifications@github.com> wrote:

Sorry, guys. I'm too sleepy to finish this now. This is as far as I will
come today.


Reply to this email directly or view it on GitHub
#15 (comment).

@kaspth
Copy link
Contributor Author

kaspth commented Aug 19, 2014

@jeremy @seuros I need some advice on what to do with the find_allowed? method.

test 'by GID with only: restriction by module no match' do
  found = GlobalID::Locator.locate(@gid, only: Forwardable)
  assert_nil found
end

The above test fails because the locator doesn't have the only restriction.

What makes the most sense is applying the restriction to all locators. This way users get that behavior for free and we don't complicate the locate method interface.
What do you guys think?

We'd essentially change locate to this:

def locate(gid, options = {})
  if gid = GlobalID.parse(gid)
    locator_for(gid).locate gid if locate_allowed?(options[:only])
  end
end

# global_id.rb
def find(options = {})
  Locator.locate(self, options) # just delegate to the app specific locator.
end

def parse_encoded_gid(gid)
new Base64.urlsafe_decode64(repad_gid(gid)) rescue nil
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ Merge issue, method is down below private now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💩 Sorry.

@jeremy
Copy link
Member

jeremy commented Aug 20, 2014

Looking good! ❤️

# end
def use(app, locator = nil, &locator_block)
raise ArgumentError, 'No locator provided. Pass a block or an object that responds to #locate.' unless locator || block_given?
raise ArgumentError, 'Invalid app name provided. App names with underscores are invalid URIs.' if app.to_s.index('_')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 for now - when #25 is merged, we'll want to use its app validator for a more thorough check.

@jeremy
Copy link
Member

jeremy commented Aug 21, 2014

Looks like this is ready to go @kaspth - could you rebase + squash?

@jeremy
Copy link
Member

jeremy commented Aug 21, 2014

@kaspth Got a test failure on 1.9.3: https://travis-ci.org/rails/globalid/jobs/33109509#L56

Move only resctriction to locator.

Memoize default locator. Privatize class methods properly.

Make app name validating public.

Use app validation on GlobalID.

Normalize app names when reading or setting locators.
@kaspth
Copy link
Contributor Author

kaspth commented Aug 21, 2014

@jeremy All done ❤️

Weird test failure. It seems 1.9.3 doesn't like an empty block, so I just inserted some text.

end
end

test 'app locator is case insensitive' do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if gid is not going to be used use _ instead or remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought of it as an extra form of documentation. If people peruse the tests they will know what the argument passed in is.

You still want me to change it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let see with @jeremy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer naming the argument that's yielded, too. Omitting the arg is an option. But this is nice and clear for anyone reading the tests to understand how the software behaves.

jeremy added a commit that referenced this pull request Aug 21, 2014
Apps can hook in their own locator.
@jeremy jeremy merged commit bda0b7e into rails:master Aug 21, 2014
@kaspth kaspth deleted the app-locater branch August 21, 2014 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants