2011-09-30 17 views
18

Diciamo che ho due database: uno per gli studenti e uno per le classi. Mi piacerebbe poter 'aggiungere' lezioni a uno studente specifico e anche essere in grado di aggiungere studenti a una classe specifica. Presumo che ho bisogno di utilizzare un tavolo join qui, ma sono un po 'perso su come usarli. Vorrei infine piace essere in grado di fare qualcosa di simile:Utilizzo di tabelle di join in ruby ​​su rotaie

@class.students.find(@student_id) 

e questo mi avrebbe detto se lo studente è in classe oppure no. So che la relazione tra classi e studenti è "has_many" e viceversa. Realizza "t.references: students" nei file di migrazione? Ho provato ad aggiungere quella linea al mio file di migrazione e poi ho provato a trovare qualcosa usando l'istruzione di cui sopra e mi ha dato un errore. Sono nuovo di RoR quindi non sono nemmeno sicuro di quale sia il modo migliore per ottenere questo risultato. Qualsiasi aiuto è apprezzato!

risposta

12

Sì, questa è una relazione molti-a-molti (la classe ha molti studenti, lo studente ha molte classi). Per questo utilizzerai una relazione has_many :through. Dai un'occhiata ai documenti per ActiveRecord::Associations (Ctrl-F per "Associazione Iscriviti Modelli").

In una migrazione, t.references :students è come si dovrebbe specificare una relazione belongs_to, in quanto aggiunge solo una colonna student_id (che può ospitare un unico ID, vale a dire uno studente). Un modello di join, tuttavia, avrà due colonne: student_id e class_id. (Per inciso, chiamare un modello di 'Class' in Ruby è in cerca di guai Posso suggerire 'Corso'.?)

+0

Puoi pubblicare il codice per i modelli Studente, Classe e join? –

55

Tutto vero quello che ha detto @Jordan, qui i passi concreti per prendere:

  1. Crea una migration: rails g model CourseStudent crea un modello di join per la relazione n: m e la migrazione alla tabella corrispondente.
  2. Modificare il file di migrazione CreateCourseStudent modo che contenga la seguente:

    class CreateCourseStudent < ActiveRecord::Migration 
        def change 
        create_table :course_students do |t| 
    
         # Your code comes here 
         t.integer :student_id 
         t.integer :course_id 
    
         # Here comes the generated code 
         t.timestamps 
        end 
        end 
    end 
    
  3. Eseguire la migrazione: rake db:migrate. Di conseguenza, la tabella di join dovrebbe ora esistere nel database.

  4. Aggiungi ai modelli il seguente codice

    class Course < ActiveRecord::Base 
        has_many :course_students 
        has_many :students, :through => :course_students 
    end 
    
    class Student < ActiveRecord::Base 
        has_many :course_students 
        has_many :courses, :through => :course_students 
    end 
    
    class CourseStudent < ActiveRecord::Base 
        belongs_to :student 
        belongs_to :course 
    end 
    

Si è ora in grado di utilizzare i metodi generati dai metodi belongs_to e has_many:

  • @course.students
  • @student.courses

Prova a trovare tutti i fatti rilevanti e frammenti nello Rails Guides, lì dovresti trovare tutte le informazioni necessarie per metterti in pista. In bocca al lupo!

+3

CourseStudent belongs_to non dovrebbe essere un simbolo. – ezis

+0

Vota! Stupefacente! Mi ha aiutato! – Askar

+0

versioni più recenti di rotaie usano questo per la migrazione: 't.integer: student_id' ' t.integer: course_id' –

12

Questa è una vecchia domanda, ma nel caso in cui qualcuno si imbatta in questo come ho fatto, ora è possibile avere le relazioni has_and_belongs_to_many.Quindi sì, si potrebbe creare una tabella di join:

create_join_table :students, :courses do |t| 
    t.integer :student_id 
    t.integer :course_id 
end 

E poi nei modelli, si potrebbe dire che uno studente has_and_belongs_to_many :courses E un corso has_and_belongs_to_many :students. Non è necessario creare una terza classe chiamata CourseStudent. Questo link ha tutte queste informazioni

+7

realtà 'create_join_table' rende automaticamente i due campi ID per voi ... è possibile utilizzare il blocco per altri campi o per indici – AlexChaffee