首页 > 解决方案 > 为什么 group 或 group_by 不能在这个版本的 rails table 上工作?

问题描述

我使用以下代码进行了此 Rails 迁移

class CreateCertificatesUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :certificates_users do |t|
      t.references :user, foreign_key: true
      t.references :certificate, foreign_key: true
    end
  end
end

在证书模型和用户模型中,我有has_many :certificates_users

这使我能够将证书添加到用户的个人资料中。目前,我有 2 个用户,并且我已经为他们添加了证书。

2.5.3 :010 > CertificatesUser.all
  CertificatesUser Load (0.6ms)  SELECT  "certificates_users".* FROM "certificates_users" LIMIT $1  [["LIMIT", 11]]
 => #<ActiveRecord::Relation [#<CertificatesUser id: 8, user_id: 1, certificate_id: 1, expiry_date: "2020-01-14", certificate_number: "1122", renewal_date: "2019-01-14", ispublic: 1>, #<CertificatesUser id: 9, user_id: 2, certificate_id: 1, expiry_date: "2020-01-16", certificate_number: "123", renewal_date: "2019-01-16", ispublic: 1>, #<CertificatesUser id: 10, user_id: 2, certificate_id: 2, expiry_date: "2019-02-28", certificate_number: "123", renewal_date: "2019-01-16", ispublic: 1>]>  

为了清楚起见,这里是certificates_users表。

id | user_id | certificate_id | ...
---+---------+----------------+----
 8 |       1 |              1 |
 9 |       2 |              1 |
10 |       2 |              2 |

一个用户有 2 个证书,另一个有一个。

我的目标是能够列出拥有某种类型证书的用户。

  1. 列出拥有 id 为 1 的证书的用户(应该列出两个用户)。- 下拉菜单 1
  2. 仅列出同时拥有 id 为 1 的证书和 id 为 2 的证书的用户(应仅列出 1 个用户)。- 下拉 2
  3. 当从其单独的下拉列表中选择此用户中的任何一个时,在另一个下拉列表中列出他们的证书。

我曾尝试使用groupgroup_by达到此结果,但没有奏效。这个想法是我正在尝试对CertificatesUserby进行分组,user_id但这没有用。它返回了这个错误:

2.5.3 :011 > CertificatesUser.group_by(&:user_id)
Traceback (most recent call last):
        1: from (irb):11
NoMethodError (undefined method `group_by' for #<Class:0x00007fa8dda7c668>)
Did you mean?  group

然后我用group方法得到了这个:

2.5.3 :012 > CertificatesUser.group('users.id')
  CertificatesUser Load (7.2ms)  SELECT  "certificates_users".* FROM "certificates_users" GROUP BY users.id LIMIT $1  [["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "users")
LINE 1: ...cates_users".* FROM "certificates_users" GROUP BY users.id L...
                                                             ^
: SELECT  "certificates_users".* FROM "certificates_users" GROUP BY users.id LIMIT $1

知道我怎样才能完成这项工作吗?

标签: ruby-on-rails

解决方案


我的目标是能够列出拥有某种类型证书的用户。

您可以使用joins

certificate_ids = [1,2] # or anything other ids
User.joins(:certificates_users).where('certificates_users.certificate_id' => certificate_ids)

关于groupgroup_by

group_by可以调用Enumerable,所以不能直接在 AR 模型上调用。你可以这样做:

CertificatesUser.all.group_by(&:user_id)

但这非常低效-您将整个表加载到内存中。

要使用group,您需要指定正确的列名。您使用users.id并且您certificates_users没有这样的字段。您可能可以使用

CertificatesUser.group('user_id')

推荐阅读