Search code examples
ruby-on-railsrubyruby-on-rails-3geokit

Geokit plus Rails 3.1.1, lat and lon issue.


I am using geokit-rails3 gem to find products in all colleges within range of particular college. A college has_many products and a product belong to college, there is another category model which has_many products and product belongs_to category. But when I try to find college from database on basis of addess using geokit it tell me lat coloumn is missing in my table.

Colleges migration is

 create_table :colleges do |t|
  t.string :name
  t.text :address
  t.string :city
  t.string :state
  t.integer :zipcode

  t.timestamps

Controller

     @products = College.within(5, :origin=>@current_product.college.address).product

Error:

     Mysql::Error: Unknown column 'colleges.lat' in 'field list': SELECT `colleges`.*, 
      (ACOS(least(1,COS(0.3223824452162744)*COS(1.2891920858347756)*COS(RADIANS(colleges.lat))*COS(RADIANS(colleges.lng))+
      COS(0.3223824452162744)*SIN(1.2891920858347756)*COS(RADIANS(colleges.lat))*SIN(RADIANS(colleges.lng))+
      SIN(0.3223824452162744)*SIN(RADIANS(colleges.lat))))*3963.19)
      AS distance FROM `colleges`  WHERE ((colleges.lat>18.398868573573203 AND colleges.lat<18.543438426426793 AND colleges.lng>73.78905443427034 AND colleges.lng<73.94147656572967)) AND ((
      (ACOS(least(1,COS(0.3223824452162744)*COS(1.2891920858347756)*COS(RADIANS(colleges.lat))*COS(RADIANS(colleges.lng))+
      COS(0.3223824452162744)*SIN(1.2891920858347756)*COS(RADIANS(colleges.lat))*SIN(RADIANS(colleges.lng))+
      SIN(0.3223824452162744)*SIN(RADIANS(colleges.lat))))*3963.19)
      <= 5))

Any hint how to solve this issue?


Solution

  • Anything that acts_as_mappable with geokit needs a lat & lnt fields (these can be overridden using different names)

    see the top of: http://geokit.rubyforge.org/readme.html

    I'd recommend:

    add_column :colleges, :lat, :float
    add_column :colleges, :lng, :float
    add_index  :colleges, [:lat, :lng]
    

    Also, to auto-update the address:

    before_save :update_location
    
    def update_location
     #you probably you to use a full address, or join all the address parts instead of just self.address
     loc=Geocoder.geocode(self.address)
     if loc.success
       self.lat = loc.lat
       self.lng = loc.lng
     end
    end