2014-07-09 51 views
0

我在我的Rails應用程序中寫了一個函數,它沒有通過氣味測試,我不確定如何重構。查找所有Obj who's Delivery半徑在地理編碼地址內

目前,用戶可以輸入表單中的地址,我的目標是吐出給定交付半徑內的任何送貨公司。現在,看起來像這樣:

class Dealers < ActiveRecord::Base 
    validates :name, presence: true 
    validates :delivery_radius, numericality: { only_integer: true } 
end 

所以搜索進入我的控制,我調用一個方法,我寫(available_deliveries)是這樣的:

@dealers = Dealer.available_deliveries(Geocoder.coordinates(search_params)) 

search_params僅僅是街道,城市&狀態。

Dealer#available_deliveries方法是這樣的:

def self.available_deliveries(geo) 
    dealers = [] 
    Dealer.all.each do |dealer| 
     if dealer.distance_from(geo) <= dealer.delivery_radius 
     dealers << dealer 
     end 
    end 
    dealers 
    end 

YIKES這是醜陋的。我不確定如何執行where SQL語句以獲得相同的結果...

+0

'distance_from'是怎麼樣的? – alexsmn

+0

Hi @ uhn-nohn'distance_from'是一個Geocoder方法,它執行此操作:'obj.distance_from([40.714,-100.234])#從任意點到對象的距離 – Anthony

回答

1

根據您的支持數據庫,我建議您根據地理空間距離使用其索引功能。

Postgresql

查找記錄在半徑

通過這些擴展提供另一個偉大的功能是 earthbox(lltoearth($latlngcube), $radiusinmetres)此功能允許 我們進行一個簡單的比較,發現在一定 所有記錄半徑。這是通過函數返回大圓點 之間的距離來完成的,更詳細的解釋位於 http://en.wikipedia.org/wiki/Greatcircle

這可以用來顯示我們目前的城市中的所有事件。

這樣的查詢的示例:

SELECT events.id, events.name FROM events WHERE earth_box({current_user_lat}, {current_user_lng}, {radius_in_metres}) @> 

ll_to_earth(events.lat,events.lng);

MySql

我們正在使用double存儲latitudelongitude。另外,我們 預先計算(通過觸發器)當 僅查看一個點時可預先計算的所有值。我目前無法訪問我們正在使用的 公式,稍後將添加此公式。這是針對 優化的速度/精度平衡而優化的。