Как получить все связанные объекты из существующего набора объектов в Rails

В приложении Rails у меня есть две модели, которые связаны через ассоциации has_many и belongs_to:

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

Я использую SearchKick, чтобы сначала выбрать несколько Entities — подробности этого не имеют большого значения, но учитывая существующую коллекцию объектов Entity, как я могу получить все связанные объекты Applicant ?

# 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.???

Это работает, но очень медленно, учитывая большой выбор:

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

Есть ли сокращение Rails для получения заявок, связанных с выбранными сущностями?

Другие вещи, которые я пробовал:

entities.class => Entity::ActiveRecord_Relation 
entities.applicants => #error
entities.applicant_ids => #error

person Stephen Lead    schedule 11.07.2016    source источник


Ответы (3)


Как это?

Applicant.joins(:entity).where("entities.id < ?", 1000)
person lusketeer    schedule 11.07.2016
comment
Спасибо, я не знал о .joins. Ваш код работает, но я упростил свой пример кода, чтобы сделать его воспроизводимым. В моем приложении я использую SearchKick, поэтому entities = Entity.search params[:query] запрос может быть сложным. Можно ли изменить ваш ответ, чтобы использовать существующий набор функций в entities (вместо включения пункта where)? - person Stephen Lead; 11.07.2016
comment
Я не знаком с searchKick, я только играл с elasticsearch, похоже, вам нужно с нетерпением загрузить ассоциацию и определить свой search_data как это, меня немного смущает то, что вы хотите найти applicants с учетом entities, тогда поиск должен быть на стороне Applicant с ассоциацией - person lusketeer; 11.07.2016
comment
да, вы могли бы быть правы насчет поиска кандидатов. Однако у сущностей есть атрибуты, которые мне нужно искать (широта/долгота в этом случае). Возможно, мне нужно реорганизовать модели и отношения, чтобы поддержать это. Спасибо за советы. - person Stephen Lead; 12.07.2016

Этот ответ пришел от Эндрю Кейна, разработчика SearchKick:

Один из способов — использовать параметр include для быстрой загрузки ассоциаций.

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

Другой вариант — получить все идентификаторы от сущностей и передать их в запрос для соискателей.

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

Я обнаружил, что второй вариант работает хорошо для меня.

person Stephen Lead    schedule 12.07.2016

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

Чтобы получить всех кандидатов

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