2015-09-15 3 views
0

У меня есть следующие модели/отношения:Rails получить коллекцию родителей от детей

class Directory < ActiveRecord::Base 
    has_one :location 
end 

class Location < ActiveRecord::Base 
    belongs_to :directory 
    geocoded_by :full_address 
end 

Location использует в geocoder камень. Каждая запись каталога имеет местоположение, а также информацию каталога (контакты, веб-сайт и т. Д.).

В directory#index, я хотел бы показать местоположения вблизи места поиска пользователя. До сих пор у меня есть:

def index 
    if params[:search].present? 
    @directories = Location.near(params[:search], 50, :order => :distance).paginate(page: params[:page], :per_page => 10) 
    else 
    @directories = Directory.order(:name).paginate(page: params[:page], :per_page => 10) 
    end 
end 

Как вернуть коллекцию записей в каталоге (родительских), соответствующих местоположению (детям)?

ответ

0

Ну, не совсем ответ на мой вопрос, но поскольку другие ответы не были получены, я вздремнул, а затем понял, что для меня это было немного XY problem.

Вместо того, чтобы генерировать коллекцию родителей (каталогов), я просто сделал то, что хотел сделать геокодер, и создал коллекцию местоположений. Затем, на мой взгляд, я просто использовал родительскую ассоциацию directory для доступа к каждому соответствующему каталогу.

Работает отлично.

0

Вы могли бы использовать что-то вроде этого:

Directory.joins(:locations).where(locations: { id: Location.near(params[:search], 50, :order => :distance) }) 

Это будет генерировать запрос, похожий на этот:

SELECT `directories`.* 
FROM `directories` 
INNER JOIN `locations` ON `locations`.`directory_id` = `directories`.`id` 
WHERE `locations`.`id` IN (SELECT `locations`.`id` FROM `locations` WHERE "your search query here") 

EDIT: Или вы можете переместить Location запрос прямо в INNER JOIN статьи:

location_query = Location.near(params[:search], 50, :order => :distance).distinct.select(:directory_id) 
directories = Directory.joins("INNER JOIN (#{location_query.to_sql}) loc ON loc.directory_id = directories.id") 

Я считаю, что запросы выше, лучше, чем прямые каталоги отображения, т.е.

directories = Location.near(params[:search], 50, :order => :distance). 
    paginate(page: params[:page], :per_page => 10).map(&:directory) 

, потому что в моем запросе вы можете применить нумерацию страниц на нужном уровне (каталоги), но здесь вы примените его к местам. Это не так хорошо, потому что, если некоторые местоположения принадлежат одному каталогу, вы получите дубликаты каталогов (если вы забыли добавить .uniq в конце вашего запроса) или более короткий список каталогов (если вы не забудете о .uniq :)).

Имейте славный день!

+0

Спасибо Алексею за подробный ответ, но он не работает для меня. Я подозреваю, что это связано с тем, что у меня есть отношение 'has_one' между родительским и дочерним, поэтому ассоциация' locations' отсутствует. Я попытался сделать это «location», но это, похоже, не помогло. Я думаю, что буду придерживаться своего подхода (не так уж плохо, поскольку у меня есть отношения к одному от родителей и ребенка), но, надеюсь, ваш ответ может помочь кому-то другому. –

+0

О, очень жаль. Я не думаю, что 'has_one' является проблемой, может быть, это' geocoder' генерирует тяжелый запрос, о котором я не знаю. Тем не менее, я рад, что вы решили свою проблему :) –

Смежные вопросы