1

In a Rails app I have two models which are related via has_many and belongs_to associations:

class Entity < ActiveRecord::Base
  has_many :applicants
end
class Applicant < ActiveRecord::Base
  belongs_to :entity
end

I'm using SearchKick to first select some Entities - the details of this don't really matter, but given an existing collection of Entity objects, how can I retrieve all of the related Applicant objects?

# select some entities (in my app I'm using SearchKick to run the search)
entities = Entity.search params[:query]

# now find the applicants related to the selected entities
applicants = entities.???

This works, but is very slow given a large selection:

# retrieve the applicants related to the selected entities
applicants = []
entities.each do |entity|
  applicants += entity.applicants
end

Is there a Rails short-hand to retrieve the Applicants related to the selected Entities?

Other things I've tried:

entities.class => Entity::ActiveRecord_Relation 
entities.applicants => #error
entities.applicant_ids => #error
Stephen Lead
  • 1,904
  • 5
  • 23
  • 46

3 Answers3

1

Like this?

Applicant.joins(:entity).where("entities.id < ?", 1000)
lusketeer
  • 1,890
  • 1
  • 12
  • 29
  • Thanks, I didn't know about `.joins`. Your code works - but I simplified my code example to make it reproducible. In my app I'm using SearchKick so `entities = Entity.search params[:query]` where the query may be complicated. Is it possible to modify your answer to use an existing set of features in `entities` (rather than including the `where` clause)? – Stephen Lead Jul 11 '16 at 13:02
  • I'm not familiar with searchKick, I only played around with elasticsearch, looks like you need to eager load the association, and define your `search_data` like [this](http://stackoverflow.com/a/21383143/1301840), it's a bit confusing to me that, you want find `applicants` given the `entities`, then the search should be on `Applicant` side with the association – lusketeer Jul 11 '16 at 13:28
  • yeah you might be right about searching on Applicants instead. However the Entities have the attributes that I need to search (lat/long in this case). Maybe I need to refactor the models and relationships to support this. Thanks for the tips so far though. – Stephen Lead Jul 11 '16 at 22:56
1

This answer came from Andrew Kane, the developer of SearchKick:

One way is to use the include option to eager load associations.

Entity.search "*", include: [:applicants]

Another option is to get all ids from the entities, and pass them into a query for applicants.

Applicant.where(entity_id: entities.map(&:id))

I found that the second option worked well for me.

Stephen Lead
  • 1,904
  • 5
  • 23
  • 46
0
Entity.where("id < ? ", 1000).includes(:applicants)

To get all applicants

Entity.where("id < ? ", 1000).includes(:applicants).collect(&:applicants).flatten