0

So I am using the geocoder gem in Rails 4.1 and have the following models setup. The code works but the Bullet gem is detecting this line places.select { |place| @countries.places.include?(place.country) } as an N+1 query. Is there a good rails-ish way to write it via eager loading? The trick is that I want to return a set of countries that only contain the places returned by the Geocoder method near.

Model setup

class Country < ActiveRecord::Base
  has_many :places
end

class Place < ActiveRecord::Base
  has_one :country
end

In some_controller.rb

@countries = Country.all
places = Place.near(some_latitude_longitude_coordinates, 5500)
places.select { |place| @countries.places.include?(place.country) }

EDIT: one correction for some_controller.rb - It should read:

places.select { |place| @countries.include?(place.country) }

As noted in the comments below, Country.all is really just a placeholder to make it easier to read the code. In actuality, @countries is really another subset of countries (as opposed to Country.all) with some property such as "all communist countries". Thus, I want to find the intersection of the countries of places near a certain set of coordinates and countries with some property such as "all communist countries".

Nona
  • 5,302
  • 7
  • 41
  • 79
  • `@countries.places.include?(place.country)` what does this do? – Tamer Shlash Sep 21 '14 at 00:40
  • Hi Tamer, that was a typo - I made the edit above, basically it is an intersection between the set of all countries and the countries of the places that have been found near some coordinates. @countries is really another subset of countries (as opposed to Country.all) with some property such as "all communist countries" – Nona Sep 21 '14 at 00:45
  • checkout my answer below. – Tamer Shlash Sep 21 '14 at 00:49

2 Answers2

0

Haven't tried it but it should work:

@countries = Country.all
places = Place.includes(:country).near(some_latitude_longitude_coordinates, 5500)
places.select { |place| @countries.include?(place.country) }

This will get you places whose countries are included in the @countries collection.

Tamer Shlash
  • 9,314
  • 5
  • 44
  • 82
0

To proper eager load your records, you need to make one query. I would suggest the following:

@places = Place.near(some_latitude_longitude_coordinates, 5500).joins(:country).where(country_id: @countries.map(&:id))
Marcelo Ribeiro
  • 1,718
  • 1
  • 13
  • 27