2012-07-19 109 views
1

我有以下型号现有的查询邻近城市:导轨 - 在它连接城市表

class User 
has_one :player 
belongs_to :city 
end 

class Player 
belongs_to :user 
end 

class City 
has_many :users 
end 

每个城市都有一个纬度经度属性。

我有以下查询(它有点长,但重要的是城市部分),我用它来获取关联用户来自特定城市的玩家。由于这样的:

def self.search(city) 
    self.includes(:user => :city). 
    where(['cities.name = ?', city]) 
end 

我将如何改变这个查询来获取教授哪些用户相关的城市附近(10公里例如)给定的城市?

编辑:我在城市模型这种方法,给了我最近的城市赋予了特定的半径(公里),纬度和经度:

def near_by(latitude,longitude,radius) 
    City.select("cities.*, 
       6371 * 
       acos(cos(radians(#{latitude})) * 
       cos(radians(cities.latitude)) * 
       cos(radians(cities.longitude) - radians(#{longitude})) + 
       sin(radians(#{latitude}))*sin(radians(cities.latitude))) 
       AS km_away").group('km_away ASC').having('km_away <= ?', radius) 
    end 

EDIT2:这里是我有这么远为了结合两个查询:

# Pass a city object to the search instead of a city name, so we can use lat and long 

def self.search(city) 
    self.includes(:user => :city). 
    where(['cities.id IN (?)', City.near_by(city.latitude,city.longitude)]) 
end 

但是,这是一个好方法?如果是这样,我怎样才能得到由接近通过的城市订购的教授?

回答

0

为了使用地理数据,我建议您按照railscast中所述检查Geocoder gem

自述: 随着地理编码的对象,你可以做这样的事情:

obj.nearbys(30)      # other objects within 30 miles 
obj.distance_from([40.714,-100.234]) # distance from arbitrary point to object 
obj.bearing_to("Paris, France")  # direction from object to arbitrary point 
+0

我觉得这更像是一个比一个答案评论......但由于反正。 – 2012-07-20 11:01:18