Zephyr4434
Zephyr4434

Reputation: 796

How to automatically show user's city with Geocoder from a list of cities

I am trying to implement a functionality that takes the visitor's IP address and returns a city name in the header of the site.

However, the city needs to be pulled from a pre-populated list of cities. I am going to populate that list with a list of major U.S. cities.

My question has three parts:

  1. What is the best way populate a static list of major cities - is it through a migration?
  2. How can I use Geocoder to return only cities from that prepopulated list? Some cities will be smaller ones that I'd like to "rolled up" into the larger cities based on their proximity to those cities
  3. How do I show the city in the header as a dropdown and set the default to the user's city based on their IP, but also let the user select a different city from that dropdown?

Currently, I am using a dedicated Location.rb model and locations_controller.rb controller.

In my model:

reverse_geocoded_by :lat, :lon do |obj,results|
  if geo = results.first
    obj.city    = geo.city
  end
end
after_validation :reverse_geocode

In my controller:

def index
    @ip = request.remote_ip
    @locations = Location.all
    @city = result.city
end

In my header partial:

<%= collection_select(@cities) %>

I am new to Rails and the GeoCoder gem so I am not sure if I am doing it correctly in terms of the code and structure. Any input would be helpful.

Upvotes: 0

Views: 632

Answers (1)

rorra
rorra

Reputation: 9693

1) The migration is not a place where you should populate any data, you can add the population of data either on the file db/seeds.rb (you usually run: rake db:create;rake db:migrate;rake db:seed). If you don't like the db/seeds.rb, you can add a custom Rake task.

2) Geocoder doesn't came with that feature out of the box, what you can do, is to store the major cities on a table, with their latitude and longitude, then do a geo ip query to check what's the user latitude/longitude, and use geocoder to search the major city closer (Model.near) to the user lat/long.

3)

def index
  @ip = request.remote_ip
  @locations = Location.all
  @lat, @lng = write_code_to_get_user_lat_and_lng
  @city = Location.near([@lat, @lng], maximum_radius_in_miles).first
end

<%= select_tag('user_city', options_for_select(@locations.collect {|l| [l.name. l.id]}, @city.id) %> 

Upvotes: 1

Related Questions