3

I'm trying to figure out where to add errors for validations to a rails 4 app that uses geocoder.

My model looks like this:

class Tutor < ActiveRecord::Base
  belongs_to :user      
  validates_presence_of :user_id

  geocoded_by :address do |obj, results|
    if geo = results.first
      obj.latitude = geo.latitude
      obj.longitude = geo.longitude
      obj.country = geo.country
      obj.city = geo.city
      obj.postalcode = geo.postal_code
      obj.address = geo.address
    end
  end
  after_validation :geocode, if: :address_changed?

end

I noticed that the if geo = result.first conditional only gets executed if the address was found successfully. I'd like to add an error message if nil is being returned. I saw that this stackoverflow thread explains that I should be using before_validation instead of after_validation, but I still don't understand where to add errors so that my view can get re-rendered and a valid geolocation can be input.

Any ideas where I should be putting this information? Thanks!

Community
  • 1
  • 1
DaniG2k
  • 4,772
  • 36
  • 77

2 Answers2

2

You can set in the model like this example below to validate address the geocode will be called only once when the address changed. In geocoded_by method we set explicitly to write latitude and longitude so than when the address would not be found those columns will be set to nil.

class Company < ActiveRecord::Base
   geocoded_by :address do |object, results|
    if results.present?
     object.latitude = results.first.latitude
     object.longitude = results.first.longitude
    else
     object.latitude = nil
     object.longitude = nil
    end
  end

  before_validation :geocode, if: :address_changed?

  validates :address, presence: true
  validates :found_address_presence

  def found_address_presence
    if latitude.blank? || longitude.blank?
      errors.add(:address, "We couldn't find the address")
    end
  end
end
ilgam
  • 4,092
  • 1
  • 35
  • 28
0

Try something like:

class Tutor < ActiveRecord::Base
  belongs_to :user      

  before_validation :geocode, if: :address_changed?

  validates :user_id, :address, presence: true

  geocoded_by :address do |obj, results|
    if geo = results.first
      obj.latitude = geo.latitude
      obj.longitude = geo.longitude
      obj.country = geo.country
      obj.city = geo.city
      obj.postalcode = geo.postal_code
      obj.address = geo.address
    else
      obj.address = nil
    end
  end
end
  • This doesn't work because, if the address has not been input in the database yet, the condition `validates :address, presence: true` will always return an error because the address gets generated by geocoder after it makes the API request. – DaniG2k Oct 11 '13 at 15:54
  • so the geocoded should make its request BEFORE validation. That's why there is a before_validation in there... – Rene van Lieshout Oct 25 '13 at 08:23