如何查询关联模型上的对象数量?
How do I query the number of objects on an associated model?
我有一个 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
与每个 profile
记录关联的 ratings
对象的数量和 return 具有超过 1
评价关联对象。
如何使用 ActiveRecord 实现?
编辑 1
根据用户 793789 的建议再尝试两个查询:
> 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)
Profile.includes(:ratings).where('ratings.count > 0').references(:ratings).count
OP 的编辑 1
几经周折,我们终于定下了这个:
Profile.joins(:ratings).group('profiles.id').having('count(ratings.id) > 0').length
但我觉得必须有更简单的方法来做到这一点。
我有一个 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
与每个 profile
记录关联的 ratings
对象的数量和 return 具有超过 1
评价关联对象。
如何使用 ActiveRecord 实现?
编辑 1
根据用户 793789 的建议再尝试两个查询:
> 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)
Profile.includes(:ratings).where('ratings.count > 0').references(:ratings).count
OP 的编辑 1
几经周折,我们终于定下了这个:
Profile.joins(:ratings).group('profiles.id').having('count(ratings.id) > 0').length
但我觉得必须有更简单的方法来做到这一点。