Как запросить количество объектов в связанной модели?

У меня есть Profileи что has_many :ratings.

То, что я хочу найти, — это количество Profileобъектов, которые имеют более 1 рейтинговой записи, связанной с ним.

Я попытался следующее безрезультатно:

> Profile.includes(:ratings).where('ratings.count > 0').count
   (38.2ms)  SELECT COUNT(*) FROM "profiles" WHERE (ratings.count > 0)
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "ratings"
LINE 1: SELECT COUNT(*) FROM "profiles" WHERE (ratings.count > 0)
                                               ^
: SELECT COUNT(*) FROM "profiles" WHERE (ratings.count > 0)

И

> Profile.where('ratings.count > 1').count
   (28.1ms)  SELECT COUNT(*) FROM "profiles" WHERE (ratings.count > 1)
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "ratings"
LINE 1: SELECT COUNT(*) FROM "profiles" WHERE (ratings.count > 1)
                                               ^
: SELECT COUNT(*) FROM "profiles" WHERE (ratings.count > 1)

Обратите внимание, что моя ratingsмодель не включает столбец с именем count. То, что я пытаюсь сделать, это countколичество ratingsобъектов, связанных с каждой profileзаписью, и возвращаю количество Profileзаписей, которые имеют больше, чем 1рейтинг связанного объекта.

Как добиться этого с помощью ActiveRecord?

Редактировать 1

Попробуйте выполнить еще два запроса на предложение user793789:

> Profile.includes(:ratings).where('ratings.count > 1').references(:ratings).count
   (55.3ms)  SELECT COUNT(DISTINCT "profiles"."id") FROM "profiles" LEFT OUTER JOIN "ratings" ON "ratings"."profile_id" = "profiles"."id" WHERE (ratings.count > 1)
ActiveRecord::StatementInvalid: PG::GroupingError: ERROR:  aggregate functions are not allowed in WHERE
LINE 1: ...N "ratings"."profile_id" = "profiles"."id" WHERE (ratings.co...
                                                             ^
: SELECT COUNT(DISTINCT "profiles"."id") FROM "profiles" LEFT OUTER JOIN "ratings" ON "ratings"."profile_id" = "profiles"."id" WHERE (ratings.count > 1)

> Profile.joins(:ratings).where('ratings.count > 1').count
   (40.4ms)  SELECT COUNT(*) FROM "profiles" INNER JOIN "ratings" ON "ratings"."profile_id" = "profiles"."id" WHERE (ratings.count > 1)
ActiveRecord::StatementInvalid: PG::GroupingError: ERROR:  aggregate functions are not allowed in WHERE
LINE 1: ...N "ratings"."profile_id" = "profiles"."id" WHERE (ratings.co...
                                                             ^
: SELECT COUNT(*) FROM "profiles" INNER JOIN "ratings" ON "ratings"."profile_id" = "profiles"."id" WHERE (ratings.count > 1)

1 ответ

  1. Profile.includes(:ratings).where('ratings.count > 0').references(:ratings).count
    

    OP Edit 1

    После много поддержки и forthing, мы окончательно установили на этом:

    Profile.joins(:ratings).group('profiles.id').having('count(ratings.id) > 0').length
    

    Но я чувствую, что должен быть более простой способ сделать это.