Найти все объекты, чей радиус доставки находится в пределах геокодированного адреса

Я написал функцию в своем приложении Rails, которая не проходит проверку на запах, и я не знаю, как провести рефакторинг.

В настоящее время пользователь может ввести адрес в форму, и моя цель — указать все компании по доставке, которые находятся в пределах заданного радиуса доставки. Прямо сейчас это выглядит так:

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, чтобы получить те же результаты...


person Anthony    schedule 09.07.2014    source источник
comment
Как выглядит distance_from?   -  person alexsmn    schedule 09.07.2014
comment
Привет, @uhn-nohn distance_from — это метод Geocoder, который делает следующее: obj.distance_from([40.714,-100.234]) # distance from arbitrary point to object   -  person Anthony    schedule 09.07.2014


Ответы (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 для хранения latitude и longitude. Кроме того, мы предварительно вычисляем (с помощью триггеров) все значения, которые можно предварительно вычислить, если рассматривать только одну точку. В настоящее время у меня нет доступа к формуле, которую мы используем, я добавлю ее позже. Это оптимизировано для оптимального баланса скорости и точности.

person Uri Agassi    schedule 09.07.2014