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)
Например: мне нужно распечатать Компании с наивысшими заданиями сверху
Ответы
Ответ 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)