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 ability to set fields in configuration for Google Places #1572

Closed
wants to merge 4 commits into from

Conversation

czlee
Copy link
Contributor

@czlee czlee commented Apr 6, 2022

Thanks so much for your work on this gem, @alexreisner!

This PR adds support for:

  1. the fields parameter to :google_places_details
  2. configuring fields in Geocoder.configure, for both :google_places_details and :google_places_search

(I know this is two things, but they're very tightly related hard-to-separate things!)

Limitation: If the Geocoder configuration has fields configured, you can't override it in the query with nil. You can override it with [], but this would add &fields=& to the query string (which does the same thing, but would look different to the cache). Open to thoughts on whether this should be modified.


Note on relationship with #1514 (@ericds): In principle they have a similar objective, and this PR includes half of #1514. However, #1514 also specifies a collection of default fields in google_places_details.rb. Instead, in this PR I propose falling back to nil, which will send a request to Google Places without the fields= key, which (at least when I do it) seems to just default to all of the keys available. Reasons I felt this was preferable:

  • retains existing/backwards functionality (i.e. if fields isn't specified, this will do the same thing as currently)
  • when the available Google Places API fields change, this gem doesn't have to be updated to match it

That said, I'd be down to discuss this with @ericds to arrive at an agreement on how this should work, for @alexreisner to consider.

@alexreisner
Copy link
Owner

Thanks for this. And apologies to @ericds for not responding to #1514 (I simply missed it). I do prefer this no-defaults approach for exactly the reasons you name. Would you mind adding a test or two, to make sure the fields get formatted properly in the query string? Also, what do you think about allowing the config to be overridden by using nil? I think that would be more expected/standard behavior (and would solve the cache problem you mentioned), but is there a reason not to do it?

@czlee
Copy link
Contributor Author

czlee commented Apr 12, 2022

Would you mind adding a test or two, to make sure the fields get formatted properly in the query string?

For sure! Will do (in the next week or so).

Also, what do you think about allowing the config to be overridden by using nil?

Yeah, I kind of agree that it's more intuitive behaviour. I think I shied away from it because it would have (at face) changed the existing behaviour of :google_places_search, which currently specifies default fields. Currently, it's:

def fields(query)
  query_fields = query.options[:fields]
  return format_fields(query_fields) if query_fields

  default_fields
end

So if you pass in

Geocoder.search("ChIJ32KaYX-AhYARNa93OffiHEk", lookup: :google_places_search, fields: nil)

it will fall back to the default_fields. If we changed it to

def fields(query)
  if query.options.has_key?(:fields)
    return format_fields(query.options[:fields])
  end

  if configuration.has_key?(:fields)
    return format_fields(configuration[:fields])
  end

  default_fields
end

Then the same fields: nil would send the request without the fields parameter (because fields(query) now returns nil), falling back to Google's defaults, which would be a change in behaviour.

The only way to fall back to default_fields would be to omit fields: completely in both query and configuration.

It's a very subtle change in behaviour, but I know that I sometimes use nil when automatically constructing keyword arguments in response to user input where I know it has effect as omitting the argument, so I worried that it might break (a minority of) existing callers.

This wouldn't matter for :google_places_details, because both the current and last-fallback behaviour is to fall back to Google's defaults (via nil), so this difference only comes into play if the new configuration[:fields] isn't set. But doing this for :google_places_details but not :google_places_search would mean the two handle fields differently, which could be counterintuitive in itself.

So... yeah, basically just a small backwards compatibility point for :google_places_search. I'd be happy with the change, but I can imagine some existing users might at least want to be notified. 🙂

@alexreisner
Copy link
Owner

Yep, good point! Let's make this a pull request for the v1.8 branch (1.8.0 will probably be the next release) and I'll mention it in the release notes.

@czlee czlee marked this pull request as draft April 19, 2022 04:35
@czlee
Copy link
Contributor Author

czlee commented Apr 19, 2022

Dumb question, but how do I run the tests? I'm used to rspec and don't really have experience with the standard library unit test framework, or anything that needs to be done to provide a test environment for gems 😅 Sorry if I missed documentation for this, I promise I looked!

Currently I get, from the directory /usr/local/bundle/bundler/gems/geocoder-<commit-hash>/test,

# ruby unit/lookups/google_places_details_test.rb
Traceback (most recent call last):
	2: from unit/lookups/google_places_details_test.rb:2:in `<main>'
	1: from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- test_helper (LoadError)

but I'm just running it in my app dev environment, which presumably isn't what the Geocoder test environment needs.

(That's why I converted the PR to a draft: I haven't actually run the tests yet to see if they pass.)

@czlee czlee force-pushed the google-places-fields-config branch from 617097a to 80341f8 Compare April 20, 2022 03:21
@czlee czlee force-pushed the google-places-fields-config branch from 80341f8 to c019697 Compare April 20, 2022 03:29
Comment on lines +36 to +54
def fields(query)
if query.options.has_key?(:fields)
return format_fields(query.options[:fields])
end

if configuration.has_key?(:fields)
return format_fields(configuration[:fields])
end

nil # use Google Places defaults
end

def format_fields(*fields)
flattened = fields.flatten.compact
return if flattened.empty?

flattened.join(',')
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This repeats code in GooglePlacesSearch; let me know if you think these methods should be abstracted out to a base class GooglePlaces < Google. I felt it was arguable whether this was enough to justify it.

Copy link
Owner

Choose a reason for hiding this comment

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

Thanks for pointing this out. I agree that it's not enough to merit the complexity of a new base class.

@czlee czlee marked this pull request as ready for review April 20, 2022 03:35
@czlee
Copy link
Contributor Author

czlee commented Apr 20, 2022

The tests were a good idea, turns out the above-discussed modification actually caused it to fail to omit the &fields= parameter, and the new tests caught it 😅

@alexreisner
Copy link
Owner

Excellent! Tests are great for that.

This looks good to me. Will merge shortly.

Thanks for the good work on this.

@alexreisner
Copy link
Owner

Closing this manually (was merged into the v1.8 branch, which Github isn't auto-marking as "merged").

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.

2 participants