-1

I am trying to put together a directory of some of the worlds best cities around the world.

I have:

    ContinentsController < ApplicationController
      def index 
      end 

      def show 
      end 
    end

    CountriesController < ApplicationController
      def index 
      end 

      def show 
      end 
    end

    CitiesController < ApplicationController
      def index 
      end 

      def show 
      end
    end

as well as:

    class Continent < ApplicationRecord
      has_many :countries
      validates :continent_name, presence: true
    end

    class Country < ApplicationRecord
      belongs_to :continent 
      has_many :cities
      validates :country_name, presence: true 
      validates :continent_id, presence: true 
    end

    class City < ApplicationRecord
     belongs_to :continent 
     belongs_to :country
     validates :city_name, presence: true 
     validates :country_id, presence: true 
     validates :continent_id, presence: true
    end

I am using the geocoder gem. How would I geocode this? City needs to be geocoded by both country_name and city_name because cities in different parts of the world can share the same name. One example is Saint Petersburg located in both Russia and the US.

    class City < ApplicationRecord
     geocoded_by :city_name
     after_validation :geocode, if: :city_name_changed?
    end

This doesn't work in the case of Saint Petersburg as it's only geocoding the city_name, not the country_name.

Thanks a lot in advance!

recnac
  • 3,744
  • 6
  • 24
  • 46
  • 1
    What are you going to do about San Jose, CA, USA; San Jose, AZ, USA; San Jose, FL, USA; San Jose, IL, USA; San Jose, NM, USA; San Jose, TX, USA; and San Jose, PR, USA? (For example) All have the same `city_name`, `country`, and `continent`. (Although all are not, arguably, some of the best cities in the world.) Also, `City belongs_to :continent` seems redundant. – jvillian Jul 31 '18 at 15:12
  • haha, thanks @jvillian, that's true! Need to include regions/provinces/states as well! – Jacob Hedengren Jul 31 '18 at 15:15

2 Answers2

3

You can do something like this:

class City < ApplicationRecord
 geocoded_by :address
 after_validation :geocode, if: :city_name_changed?

 def address
   "#{city_name}, #{country_name}"
 end
end

The documentation shows this:

def address
  [street, city, state, country].compact.join(', ')
end

https://github.com/alexreisner/geocoder#geocoding-objects

luisenrike
  • 2,742
  • 17
  • 23
0

Geocoding doesn't need to be a column, it can be an instance method

class City < ApplicationRecord

  geocoded_by :address

  def address
    [city_name, country_name].compact.join(', ')
  end

end
SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53