Jseb
Jseb

Reputation: 1934

Rails geocode two ways in model

I am using geocoder and have a model called Location. This models contains longitude, latitude, and address. What I would like is to give the option to the user to fill in either longitude and latitude or the address. If one of them is fill up then fill up the remaining information. So here what I did

  before_validation :check
  def check
    if self.address.blank?
        reverse()
    else
        geo()
    end
  end

  def reverse
    reverse_geocoded_by :latitude, :longitude,
    :address => :address
    after_validation :reverse_geocode
  end

  def geo
    geocoded_by :address
    after_validation :geocode
  end

But i am getting the following undefined method reverse_geocoded_by I am not sure what to do!

Upvotes: 1

Views: 774

Answers (1)

tadman
tadman

Reputation: 211540

You can't call class methods inside an instance method. Remember that geocoded_by is probably defined for your model class. You cannot arbitrarily change the validations of one instance without affecting all instances of the model, so this is generally viewed as a bad idea.

You might be better off having a "Location" model that can be geocoded one of two different ways, and creating a sub-class for each encoding type. That is, the rules can be established for each of these independently. Storing these is easy using Single Table Inheritance (STI).

So you could have:

class Location < ActiveRecord::Base
end

class ForwardLocation < Location
  geocoded_by :address
  after_validation :geocode
end

class ReverseLocation < Location
  reverse_geocoded_by :latitude, :longitude,
    :address => :address
  after_validation :reverse_geocode
end

Then you'd add the proper location accordingly:

self.location = self.address? ? ReverseLocation.create(...) : ForwardLocation.create(...)

You could also write methods that handle populating the fields more directly than having to use subclasses like this, but it depends entirely on the kind of data you're receiving and processing.

As a rule, a class should have only one set of before/after callbacks. It can have some of these callbacks triggered conditionally if the callback definition supports an :if style declaration. Sometimes you need to write your own before_validation routines to handle your more exotic requirements.

Upvotes: 3

Related Questions