0

I'm trying to get nearby users from a given location. I have users latitude and longitude(I'm taking out from their address).

Now when I'm searching a term like 'NC' its showing some of its results, But when I'm searching with the country name 'Unites States', it must show all the results but instead it doesn't show any result.

I'm using Geocoder gem for this. Here's what I'm doing:

controller :

@user = User.near(params[:search], 20, :order => :distance)

Model:

geocoded_by :address1 

View :

 Displaying all the results returned from @user

Any Idea what I should do so that it will return all results even if I search with a country name.

Sachin Prasad
  • 5,365
  • 12
  • 54
  • 101
  • Does it work if you put in more specific search term? (New York for example?) – Mike Szyndel Jul 30 '13 at 10:51
  • @MichaelSzyndel Yeah it works for specific terms like if I'm using a zip code. – Sachin Prasad Jul 30 '13 at 10:53
  • So what's the point of using Geocoding to search for a COUNTRY? – Mike Szyndel Jul 30 '13 at 10:55
  • @MichaelSzyndel Shouldn't it return the result even if I'm searching it with a country? Or just say my users can't search with a country name? – Sachin Prasad Jul 30 '13 at 10:56
  • Maybe not, because radius od US is way bigger than 20 miles? Or the middle of US is nowhere, and you have to increase the radius? And I think it's pretty dumb to user geocoding for something that should be stored in DB (country, state, city) – Mike Szyndel Jul 30 '13 at 10:58

2 Answers2

1

When Geocoder receive something like 'US', it will pick a single central coordinates pair and then search from it. So in your case, it will search for users within 20 miles from the center of US.

What you want to do, is to geocode the search and then find out which kind of input it was (country etc.)

So, for example, in your controller:

def search
  search = Geocoder.search(params[:search]).first

  if search.types.includes?('country')
    @users = User.where(country: search.address)
  else
    @users = User.near(search.coordinates, 20) # Will be ordered by distance by default
  end
end

You have to store the address components in you database.

The best way to have consistent data is to run a custom geocode callback:

class User < ActiveRecord::Base
  geocoded_by :address do |obj, results|
    if result = results.first
      obj.street = result.street_address
      obj.zip = result.postal_code
      obj.city = result.city
      obj.country = result.country
      obj.latitude = result.latitude
      obj.longitude = result.longitude
    end
  end

  after_validation :geocode, if: :address_changed?

  def address
    "#{street}, #{zip} #{city}, #{country}"
  end

  def address_changed?
    street_changed? || city_changed? || zip_changed? || country_changed?
  end
end
Damien
  • 26,933
  • 7
  • 39
  • 40
0

The accepted answer by @delba is great there is only one little typo and that is, Ruby doesn't have :includes? predicate for arrays , but :include?. So it should be search.types.include?('country').

Vlatko Ristovski
  • 111
  • 1
  • 11