My solution that works for now, may be not the best one, just can't find any other:
address = [lat, long]
users.each do |u|
if u.distance_to(address, :units => :kms) < u.distance
tutors << t
end
end
how it works:
User table has a field called distance where I keep an integer that shows what is the radius that user covers, for ex: 20.
When doing a search I am sending lat and long params from the form to find a position on map, and then just loop trough users to find all users where distance between them and this point is less than the distance value.
For example: User 1 has a range of 20 km, so distance value is 20, then check if distance between User 1 and point on map is less than 20 load him in array.
I wouldn't have to much users to loop through as I limit their number in the code that goes before this so I get only a few of them.. between 1 and 40 max.
For now it works, if anyone has a better solution please share.
A better sollution:
def find_tutors
lat_d = Geokit::Mappable::LATITUDE_DEGREES
km_lat = Geokit::Mappable::KMS_PER_LATITUDE_DEGREE
kms_per_mile = Geokit::Mappable::KMS_PER_MILE
users = User.joins(:courses).where("courses.lesson ILIKE ?", "%#{lesson}%")
if long.present?
users = users.where("pow((longitude - ?) * (#{lat_d} * #{kms_per_mile} * abs(cos(0.0174 * longitude))), 2) +
pow((latitude - ?) * #{km_lat}, 2) < pow(distance, 2)",
long, lat)
end
users
end
In the case above longitude
and latitude
are attributes of search model, but could be also any other attributes.