1
votes

It works if address and reverse_geocoded_by are in the class which I don't need (latitude and longitude comes from rest client).

To find all locates within 5 miles

Locate.near([center.latitude, center.longitude], 5)

Schema

create_table :locate do |t|
  t.integer :user_id
  # t.string :address
  t.float :latitude
  t.float :longitude

  t.timestamps
end

Model Class

class Locate < ApplicationRecord

  # reverse_geocoded_by :latitude, :longitude
  # after_validation :reverse_geocode, unless: -> (obj) { obj.address.present? },
        #   if: -> (obj) { obj.latitude.present? and obj.latitude.present? and ( obj.latitude_changed? || obj.longitude_changed? ) }
end

Controller method

def near
  center = @user.locate
  render json: Locate.near([center.latitude, center.longitude], 5, units: :km)
end

Error:

NoMethodError (undefined method `near' for #Class:#):
2

2 Answers

0
votes

Geocoder needs to know which columns store latitudes and longitudes, or how to get the location for the instance to do any calculation. So you need to set either geocoded_by or reverse_geocoded_by. (the reason is that without knowing either of these information, geocoder cannot know the location of your objects, so cannot calculate the distance between any objects and your supplied location).

0
votes

Geocoder does not add these scope methods to every model. It requires you to add either geocoded_by or reverse_geocoded_by to your model if you want it to gain the Geocoder methods and scopes like .near, .geocoded, etc...

Making a call to one of these two class macros is the hook that configures the geocoding options and extends your model with these methods. Again, Geocoder does not add these methods directly to ActiveRecord::Base and by extension every model in your application. Geocoder does not infer simply from the presence of latitude:float longitude:float in your schema that you want the model to be "geocodable". Geocoder does not go looking for these columns in any of your tables at all.

This is the bare minimum you'll have to do to get the functionality you're looking for

reverse_geocoded_by :latitude, :longitude

Think of it like this: If you add post_id:integer to your Comment model, do you automatically get a #post method? No, you have to explicitly add belongs_to :post. This is exactly the same idea.