1

Rails 5.Ruby on Rails: has_many auto rejoindre

Je suis en train de créer une relation has_many de référencement auto basé sur ce tutoriel: https://medium.com/@jbmilgrom/active-record-many-to-many-self-join-table-e0992c27c1e (la dernière pièce: has_many | has_many - Self table de jointure)

Je vois aussi différents sujets ici à propos de ce concept mais je suis encore un peu perdu quand il s'agit de mon problème et de sa terminologie. Et je ne suis pas sûr de ce que la base de données devrait ressembler. Je devrais également mentionner que je suis très nouveau à Rails. J'essaie de créer une relation «représentative» - «représentée» entre les utilisateurs.

Un utilisateur peut être représenté par de nombreux utilisateurs (l'utilisateur a plusieurs représentants). Et un utilisateur peut représenter de nombreux utilisateurs (l'utilisateur a_many représenté).

Basé sur le tutoriel dans le lien ci-dessus, j'ai écrit mon modèle utilisateur comme ceci:

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 

Ensuite, je créé un représentant table comme si (je l'ai appelé des représentants, mais il est vraiment le groupe de représentants et représentais) :

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 

J'ai aussi créé une table de représentants dans la base de données qui ressemble à ceci:

+----------------------+------------+------+-----+---------+----------------+ 
| 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 |    | 
+----------------------+------------+------+-----+---------+----------------+ 

Ainsi, la console Rails je crée deux utilisateurs:

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

Je veux u2 représenter u1:

u1.representatives = [u2] 

Mais je reçois cette erreur:

NameError: uninitialized constant User::representatives 

Je suis trouver ce concept assez déroutant et les autres discussions ici ne me l'éclaircissent pas. Quelqu'un peut-il casser ce concept par rapport à mon problème?

+0

Copie possible de [Rails: schéma de jointure libre avec has \ _et \ _belongs \ _to \ _many?] (Https://stackoverflow.com/questions/19770888/rails-self-join-scheme-with-has -and-appartient-à-plusieurs) – BookOfGreg

Répondre

0

Ok donc à la fin je l'ai eu à travailler avec une légère modification. D'abord, j'ai renommé certaines choses pour qu'elles aient un peu plus de sens (ne serait-ce que dans ma tête).

modèle utilisateur:

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 

modèle RepresentativeGrouping:

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

la table representative_grouping:

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 |    | 
+-------------------+------------+------+-----+---------+----------------+ 

Une chose qui est essentiel est l'arrangement ici des a définitions _many dans le modèle de l'utilisateur. Dans la question à propos de vous verrez que la définition de has_many avec le travers: et source: il était en dessous de la définition has_many avec le nom de classe: et foreign_key :.Après avoir changé les noms autour je suis passé ma première erreur:

NameError: uninitialized constant User::representatives 

Mais déplacé à une autre erreur:

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

googler m'a conduit ici: https://github.com/rails/rails/issues/29123, où quelqu'un a évoqué la question avec le arrangement des définitions, et que vous devez les avoir dans le revers de ma commande.

Après ces changements que j'ai pu exécuter du code comme ceci:

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 
0

Dans userModel

Pour représentants - has_and_belongs_to_many :representatives, class_name: "User", join_table: : representative_groupings, foreign_key: :represented_id, association_foreign_key: : representative_id

Pour obtenir represented_by - has_and_belongs_to_many : represented, class_name: "User", join_table: : representative_groupings, foreign_key: :representative_id, association_foreign_key: : represented_id

This also eliminates the need for your explicit model rails - RepresentativeGrouping