ascherman
ascherman

Reputation: 1832

Rails: Valid addresses using Geocoder

I have a rails app and i've installed the geocoder gem.

I have the company class:

class Company < ActiveRecord::Base
  geocoded_by :address
  validates :address, presence: true
  after_validation :geocode, :if => :address_changed?
end

The problem is that i want the user fill the complete address of the company... but if the user write something like

Miami, FL, United States

It is allowed... but this is a problem because i want the complete address, with the street and height.

How can i achieve that?

Upvotes: 1

Views: 3158

Answers (1)

dgilperez
dgilperez

Reputation: 10796

What you are defining is not a geocoder issue, but a data-model issue: you require your users to input full addresses, so your app needs to understand and handle that. The geocoding service will try to geocode any string you pass it, no matter the resolution of the query.

Build a validation for address so you can decide whether or not call :geocode. I can see two approaches depending on whether you want to allow the user to store addresses like "Miami, FL, United States" and not geocode that, or if you want to forbid the user to input partial addresses. I'll go for the latter, you'll see that the first can be derived with little modifications.

In any case, considering that there is no standard address format (you can't or will find difficult build a Regex to test that, for instance), you need to handle the different parts separately and add the required attributes to your model and form for a full address to be stored.

class ExtendAddress < ActiveRecord::Migration
  def change
    add_column :companies, :country, :string
    add_column :companies, :state, :string
    add_column :companies, :city, :string
    add_column :companies, :street, :string
    add_column :companies, :street_number, :string
    add_column :companies, :zipcode, :string

    remove_column :companies, :address # if you have data you want to reuse, you'd need to build a method for that before removing the column
  end
end

In your model, if you want only full addresses in your DB, then you can use validations for that:

class Company < ActiveRecord::Base
  validates :street, :street_number, :zipcode, :city, :state, :country, presence: true

  geocoded_by :address
  after_validation :geocode, :if => :address_changed?

  def address
    # or whatever format you prefer
    [street, street_number, zipcode, city, state, country].join(',')
  end
end

I'm not writing here the form code, I'm sure you know how to build that. Also, an Address may have different number of attributes for you, take this just as a suggestion. Also, in the long run, you should consider turning Address into a first level citizen and have a separate AR model for that.

Upvotes: 2

Related Questions