Search code examples
ruby-on-railsrubyruby-on-rails-3rails-geocoder

search nearby location with country name not working with geocoder


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.


Solution

  • 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