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

Ruby on Rails:has_many self-join

  •  1
  • ThriceGood  · 技术社区  · 7 年前

    轨道5。

    https://medium.com/@jbmilgrom/active-record-many-to-many-self-join-table-e0992c27c1e (最后一块:Has|manySelf连接表)

    我试图在用户之间建立“代表性”关系。

    基于上面链接中的教程,我编写了如下用户模型:

    class User < ApplicationRecord
      has_many :representatives, through: :representive_link, source: :representative
      has_many :representive_link, foreign_key: :represented_user_id, class_name: 'representatives'
    
      has_many :represented, through: :represented_link, source: :represented
      has_many :represented_link, foreign_key: :representative_user_id, class_name: 'representatives'
    end
    

    class Representatives < ActiveRecord::Base
      belongs_to :representative, foreign_key: 'representative_user_id', class_name: 'User'
      belongs_to :represented, foreign_key: 'represented_user_id', class_name: 'User'
    end
    

    我还在数据库中创建了一个代表表,如下所示:

    +----------------------+------------+------+-----+---------+----------------+
    | Field                | Type       | Null | Key | Default | Extra          |
    +----------------------+------------+------+-----+---------+----------------+
    | id                   | bigint(20) | NO   | PRI | NULL    | auto_increment |
    | representive_user_id | bigint(20) | YES  | MUL | NULL    |                |
    | represented_user_id  | bigint(20) | YES  | MUL | NULL    |                |
    | created_at           | datetime   | NO   |     | NULL    |                |
    | updated_at           | datetime   | NO   |     | NULL    |                |
    +----------------------+------------+------+-----+---------+----------------+
    

    因此,在Rails控制台中,我创建了两个用户:

    u1 = User.create('id' => 1, 'username' => 'john')
    u2 = User.create('id' => 2, 'username' => 'mike')
    

    我希望u2代表u1:

    u1.representatives = [u2]
    

    NameError: uninitialized constant User::representatives
    

    我发现这个概念很混乱,这里的其他帖子并没有为我澄清。有人能就我的问题打破这个概念吗?

    2 回复  |  直到 7 年前
        1
  •  0
  •   ThriceGood    7 年前

    好的,最后我对它进行了一些轻微的修改。首先,我重命名了一些东西,使其更有意义(如果只是在我的脑海中)。

    用户模型:

    class User < ApplicationRecord
      has_many :represented_link, foreign_key: :representative_id, class_name: 'RepresentativeGrouping'
      has_many :represented, through: :represented_link, source: :represented
    
      has_many :representive_link, foreign_key: :represented_id, class_name: 'RepresentativeGrouping'
      has_many :representatives, through: :representive_link, source: :representative
    end
    

    代表性组合模型:

    class RepresentativeGrouping < ApplicationRecord
      belongs_to :representative, foreign_key: 'representative_id', class_name: 'User'
      belongs_to :represented, foreign_key: 'represented_id', class_name: 'User'
    end
    

    mysql> describe representative_groupings;
    +-------------------+------------+------+-----+---------+----------------+
    | Field             | Type       | Null | Key | Default | Extra          |
    +-------------------+------------+------+-----+---------+----------------+
    | id                | bigint(20) | NO   | PRI | NULL    | auto_increment |
    | representative_id | bigint(20) | YES  | MUL | NULL    |                |
    | represented_id    | bigint(20) | YES  | MUL | NULL    |                |
    | created_at        | datetime   | NO   |     | NULL    |                |
    | updated_at        | datetime   | NO   |     | NULL    |                |
    +-------------------+------------+------+-----+---------+----------------+
    

    这里至关重要的一点是用户模型中有许多定义的排列。在关于的问题中,您会看到其中包含through:和source:的has\u many定义位于下面,has\u many定义具有class\u name:和foreign\u key:。在我更改了周围的名称后,我通过了我的第一个错误:

    NameError: uninitialized constant User::representatives
    

    但接着又出现了另一个错误:

    ActiveRecord::HasManyThroughOrderError: Cannot have a has_many :through association 'User#representatives' which goes through 'User#representive_link' before the through association is defined.
    

    Google引导我来到这里: https://github.com/rails/rails/issues/29123

    在这些更改之后,我能够运行以下代码:

    u1 = User.create(:id => 1, :username => 'john')
    u2 = User.create(:id => 2, :username => 'mike')
    
    u1.representatives = [u2]
    puts u1.representatives
    
    ### displays u2's data
    
    puts u2.represented
    
    ### displays u1's data
    
        2
  •  0
  •   Gaudam Thiyagarajan    7 年前

    得到 - has_and_belongs_to_many :representatives, class_name: "User", join_table: : representative_groupings, foreign_key: :represented_id, association_foreign_key: : representative_id

    得到 - has_and_belongs_to_many : represented, class_name: "User", join_table: : representative_groupings, foreign_key: :representative_id, association_foreign_key: : represented_id

    这也消除了对显式模型的需要 -