Подтвердить что ты не робот

Rails упорядочивает по результатам подсчет has_many association

В любом случае я могу заказать результаты (ASC/DESC) по числу элементов, возвращаемых из дочерней модели (Jobs)?

@featured_companies = Company.joins(:jobs).group(Job.arel_table[:company_id]).order(Job.arel_table[:company_id].count).limit(10)

Например: мне нужно распечатать Компании с наивысшими заданиями сверху

4b9b3361

Ответ 1

Если вы планируете часто использовать этот запрос, я предлагаю вам использовать встроенный counter_cache

# Job Model
class Job < ActiveRecord::Base
  belongs_to :company, counter_cache: true
  # ...
end

# add a migration
add_column :company, :jobs_count, :integer, default: 0

# Company model
class Company < ActiveRecord::Base
  scope :featured, order('jobs_count DESC')
  # ...
end

а затем используйте его как

@featured_company = Company.featured

Ответ 2

Рельсы 5 +

Поддержка левых внешних объединений была введена в Rails 5, поэтому вы можете использовать внешнее соединение вместо использования counter_cache для этого. Таким образом, вы все равно сохраните записи, имеющие 0 отношений:

Company
  .left_joins(:jobs)
  .group(:id)
  .order('COUNT(jobs.id) DESC')
  .limit(10)

SQL-эквивалент запроса - это (получен путем вызова .to_sql на нем):

SELECT "companies".* FROM "companies" LEFT OUTER JOIN "jobs" ON "jobs"."company_id" = "companies"."id" GROUP BY "company"."id" ORDER BY COUNT(jobs.id) DESC

Ответ 3

Что-то вроде:

Company.joins(:jobs).group("jobs.company_id").order("count(jobs.company_id) desc")

Ответ 4

@user24359 правильным является:

Company.joins(:jobs).group("companies.id").order("count(companies.id) DESC")

Ответ 5

Добавлено в ответ Тан. Включить 0 ассоциацию

Company.joins("left join jobs on jobs.company_id = companies.id").group("companies.id").order("count(companies.id) DESC")

по умолчанию в joins используется внутреннее соединение. Я пытался использовать left join чтобы включить 0 ассоциаций

Ответ 6

Company.where("condition here...")
       .left_joins(:jobs)
       .group(:id)
       .order('COUNT(jobs.id) DESC')
       .limit(10)