Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Geocoder rails, check if valid

Below is my class that I am using geocoder with. I am having trouble checking whether or not address that is put through geocoder is valid. This code works great when I am adding a company/editing a company that has addresses that when put through geocoder gives a latitude and longitude. But I need the code to work so when a user tries to put a address that does not give a latitude and longitude, on either an edit or creation of a company, that an error pops up and informs the user that the address is invalid.

Model

class Company < ActiveRecord::Base
    validates :name, presence: true, length: { maximum: 30 }
    validates :website, presence: true
    validates :address, presence: true
    validates :description, presence: true
    validates :primary_field, presence: true

    geocoded_by :address
    before_save :geocode, if: ->(obj){ obj.address.present? and obj.address_changed? }

    after_save :set_popup_value

    private

     ...

end

View

<% provide(:title, 'Add Company') %>
<h1>Add Company</h1>
<div class="row">
  <div class="span6 offset3">
    <%= form_for(@company) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :website %>
      <%= f.text_field :website %>

      <%= f.label :primary_field %>
      <%= f.select :primary_field, @primary_field %>

      <%= f.label :address %>
      <%= f.text_field :address, :placeholder => '123 Test St, City State Zip'%>

      <%= f.label :description %>
      <%= f.text_area :description, :size => "30x5" %>

      <%= f.submit "Add Company", class: "btn btn-large btn-primary" %>
    <% end %>
  </div>
</div>
like image 440
Scalahansolo Avatar asked Apr 15 '14 17:04

Scalahansolo


1 Answers

So, having been able to tinker around with this for a few days I have come up with a couple solutions. The first was really hacky, but accomplished what I needed. My second solution is much more elegant and works great from what I have been able to tell so far! I hope others find this useful.

I handle all of the logic in my controller in just a few lines.

geocoded_by :address
after_validation :geocode, if: ->(obj){ obj.address.present? and obj.address_changed? }
after_validation :lat_changed?

after_save :set_popup_value

private

# This is used to make sure that our address is actually parsed properly and we
# get a valuable lat/long
def lat_changed?
    if (self.address_changed?)
        if !(self.latitude_changed?)
            self.errors.add(:address, "is not valid")
            return false
        end
    end
    return true
end

By creating another after_validation after my geocode, I am able to check if the appropriate values changed, and if they changed in a certain way, than I know there was an issue in the geocoding.

If the address changed, but the latitude didnt change, than you know that when the address got put through geocoder that it didn't get a returned lat/long. And if that is the case then we just add an error to throw to the user and return false, which stops the save to the database.

I hope others with this issue are able to find this post!

like image 74
Scalahansolo Avatar answered Oct 10 '22 00:10

Scalahansolo