代码之家  ›  专栏  ›  技术社区  ›  mayorsanmayor

如何与Rails 5中的has\u many through进行分组

  •  0
  • mayorsanmayor  · 技术社区  · 7 年前

    我有以下联想:

    class Certificate < ApplicationRecord
      has_many :certificates_users
      has_many :users, :through => :certificates_users
    end
    
    class CertificatesUser < ApplicationRecord
      belongs_to :user
      belongs_to :certificate
    end
    
    class User < ApplicationRecord
      has_many :certificates_users, :dependent => :delete_all
      has_many :certificates, :through => :certificates_users
    end
    

    我正在尝试获取证书列表,然后按用户对其进行分组。基本上,列出所有用户并在其下显示其证书的子列表。下面是 UI looks like 只需点击桌子上的“市长”。

    CertificatesUser 桌子

    => CertificatesUser(certificate_id: integer, user_id: integer, expiry_date: date, certificate_number: string, renewal_date: date, ispublic: integer)
    

    answer ,我能够提出这些可能的解决方案,

    Certificate.joins(:users).group('users.id').select('users.id')
    
    User.joins(:certificates).group('certificates.id').select('certificates.id, certificates.name')
    

    这里的问题是我需要的大部分字段都在 certificates_users certificates 桌子。

    这是另一次尝试,试图让它工作,但没有工作- CertificatesUser.group(:user_id).select('user.id')

    还有什么其他可能的解决办法?

    enter image description here

    3 回复  |  直到 7 年前
        1
  •  3
  •   PGill    7 年前

    @users = User.includes(certificates_users: [:certificate])
    

    然后你可以在它们之间循环

    @users.each do |u|
      u.certificates_users.each do |cu|
       cu.certificate_number
       cu.certificate.some_column
       ...
      end
    end
    

    仅获取具有证书的用户

    @users = User.includes(certificates_users: [:certificate]).where("certificates_users.user_id = users.id")
    
        2
  •  0
  •   Shiko    7 年前

    根据您的模型中定义的关系,以下内容应适用:

    CertificatesUser.joins(:user, :certificate)        
        .select('user_id, users.name, users.email, certificates.name')
        .group_by(&:user_id)
    

    .group_by(&:user_id) 要根据json数组中的用户\ id对获取的数据进行分组,如下所示:

    结果样本:

    [1, [{ user_id: 1, certificate_id: 29, ....},{ user_id: 1, certificate_id: 22, ....}] ,
    2, [{ user_id: 2, certificate_id: 34, ....},{ user_id: 2, certificate_id: 56, ....}] ,
    3, [{ user_id: 3, certificate_id: 29, ....},{ user_id: 3, certificate_id: 12, ....}] ]
    


    您可以从中添加字段 用户 证书 但一定要用在 而不是在 .

        3
  •  0
  •   mayorsanmayor    7 年前

    在控制器里,我有这个

    @users_and_certificates = CertificatesUser.all.each_with_object({}) { |item, hash| hash[item.user_id] = item }
    

    .card-body.table-responsive
      %table.table.table-hover.table-valign-middle
        %thead
          %tr
            %th Name
            %th E-mail
        %tbody
          - @users_and_certificates.each do |user_id, certificate_object|
             %tr{"data-target" => "#certificate_#{certificate_object.certificate_id}", "data-toggle" => "collapse"}
               - user = User.find(user_id)
               %td
                 = user.full_name
               %td
                 = user.email
             %tr
               %td.card-body.table-responsive.collapse{'id' => "certificate_#{certificate_object.certificate_id}"}
                 %table.table.table-hover.table-valign-middle
                   %thead
                     %tr
                       %th Certificate
                       %th Certificate No.
                       %th Expiry Date
                       %th Certificate
                   %tbody
                     %tr
                       - certificate = Certificate.find(certificate_object.certificate_id)
                       %td
                         = certificate.name
                       %td
                         = certificate_object.certificate_number
                       %td
                         = certificate_object.expiry_date
                       %td Show
    

    目前这个效果非常好。

    谢谢。

    推荐文章