2014-11-20 1 views
0

Im on Rails 4 с использованием геокодера для управления местоположениями.Как отсортировать массив записей по расстоянию с помощью геокодирования на связанной модели?

У меня есть и ее местоположении две модели

Листинг

class Listing < ActiveRecord::Base 
    has_many :locations 
end 

Расположение

class Location < ActiveRecord::Base 
    belongs_to :listing 
    geocoded_by :full_address 
    after_validation :geocode 

    def full_address 
    [street, city, state, country].compact.join(", ") 
    end 
end 

Я пытаюсь сделать простую функцию поиска, где пользователь вводит в городе и возвращается список списков, которые находятся в 50 милях от моря rch-запрос.

У меня есть функция поиска обрабатывается в моих контроллерах перечислений указательных действий

def index 
    @query = Geocoder.search(params[:q]).first 
    @location = Location.near(@query.address, 50).order("distance") 
    @listings = Listing.find(@location.map(&:listing_id)) 
end 

Я хочу, чтобы результаты возвращаются заказываются по расстоянию до города искал. Когда я выполняю поиск, возвращаемые результаты упорядочиваются идентификаторами листинга.

Единственный способ Ive был в состоянии сделать эту работу, должен был сделать свою переменную @listings как так

def index 
    @query = Geocoder.search(params[:q]).first 
    @location = Location.near(@query.address, 50).order("distance") 
    @listings = [] 
    @location.each do |l| 
     @listings.push(Listing.find(l)) 
    end 
end 

Но это работает кучу дб запросов Query и Im обеспокоены тем, что с большим количеством записей и поиска , на db будет много напряжения.

Есть ли более сжатый способ упорядочения массива так, как я хочу? Благодарю.

ответ

0

ActiveRecord.find принимает массив и в этом случае выполняет один запрос. Так что если вы можете сделать Listing.find для отдельного места, то это так же легко сделать это для всего массива:

def index 
    @query = Geocoder.search(params[:q]).first 
    @location = Location.near(@query.address, 50).order("distance") 
    @listings = Listing.find(@location) 
end 

Это должно затем сделать три запроса: поиск Geocoder, местоположение запроса, то один запрос Листинг ,

(я бы не стал его оптимизации больше на данный момент.)

+0

Спасибо за ответ, но когда я сделаю ваше предложение, я получаю сообщение «Не могу посетить место». – oobie11

+0

Я не знаю этих классов точно, возможно, вместо '@ location' попробовать' @ location.to_a'. –

+0

Не уверен, что это даст вам то, что вы хотите. Если '@ location' содержит записи местоположения с идентификаторами [1, 3, 4, 12]' Listing.find (@location) 'будет возвращать записи записей с этими идентификаторами (т.е. [1,3,4,12]), а не записи, относящиеся к записи местоположения [1,3,4,12]. –

0

Так я понял, лучший способ сортировки мой массив Листинг.

 @listings = Listing.find(@location.map(&:listing_id)).sort_by{|listing| listing.locations.first.distance_to(@query.address)} 

Im вероятно, столкнуться с проблемами в будущем, когда я добавить возможность иметь несколько размещений за листинг в будущем, но это работает сейчас и Ill крест, мост вэнь я пришел к нему,