Reputation: 2629
I have the following models/relationships:
class Directory < ActiveRecord::Base
has_one :location
end
class Location < ActiveRecord::Base
belongs_to :directory
geocoded_by :full_address
end
Location
uses the geocoder
gem. Each directory entry has a location, along with directory information (contacts, website, etc).
In directory#index
, I would like to show locations near the user's search location. So far I have:
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
How can return a collection of directory (parent) entries corresponding to locations (children)?
Upvotes: 1
Views: 305
Reputation: 7482
You could use something like this:
Directory.joins(:locations).where(locations: { id: Location.near(params[:search], 50, :order => :distance) })
This will generate a query similar to this:
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: Or you can move the Location
query right into INNER JOIN
clause:
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")
I believe the queries above are better than direct mapping directories, i.e.
directories = Location.near(params[:search], 50, :order => :distance).
paginate(page: params[:page], :per_page => 10).map(&:directory)
because in my query you can apply pagination at the right level (directories), but here you apply it to locations. This is not so good, because if some locations belong to same directory, you'll end up with duplicate directories (if you forget to add .uniq
at the end of your query) or a shorter directories list (if you don't forget about .uniq
:) ).
Have a nice day!
Upvotes: 1
Reputation: 2629
Well, not strictly an answer to my question, but since other answers have not been forthcoming, I took a nap and then realized that this was a bit of an XY problem for me.
Rather than generating a collection of parents (directories), I just did what the geocoder gem wanted to do and generated a collection of locations. Then, in my view, I just used the directory
parent association to get to each corresponding directory.
Works perfectly.
Upvotes: 0