2017-10-05 2 views
-1

J'ai une situation où un CourseSession appartient à un Course, qui appartient à un Program. Dans mon contrôleur, j'aimerais obtenir le nom du programme de CourseSession. J'ai regardé autour et j'ai vu beaucoup de gens suggèrent d'utiliser la méthode joins. Malheureusement pour moi cela n'a pas fonctionné dans mon cas. Je reçois cette erreur:Création d'une requête "joins" 2 associations up

Can't join 'CourseSession' to association named 'program'; perhaps you misspelled it? 

Qu'est-ce que je fais mal?

@sessions = if params[:program] 
    CourseSession.joins(:course).joins(:program).where("program.name = params[:program]") 
else 
    CourseSession.all 
end 

class Program < ApplicationRecord 
    has_many :courses, dependent: :nullify 
end 

class Course < ApplicationRecord 
    has_many :sessions, class_name: "CourseSession", inverse_of: :course, dependent: :destroy 

    belongs_to :program 
end 

class CourseSession < ApplicationRecord 
    belongs_to :course 
end 

Répondre

0

Lorsque vous utilisez CourseSession.joins(:course).joins(:program) (c.-à-Enchaînement joint), vous êtes juste se joindre à la table course_sessions avec table courses et programs la table d'où la Erreur.

Ce que vous avez demandé peut être réalisé en utilisant la syntaxe suivante:

CourseSession.joins(course: :program) 

Ici, courses et programs tableau sont joints intérieur et course_sessions et courses tableau sont joints intérieure.

Le deuxième problème est dans la méthode where. Les noms des tables sont au pluriel par convention, donc vous devriez utiliser programs.name au lieu de program.name. Essayez plutôt ce qui suit:

CourseSession.joins(course: :program).where("programs.name = ?", params[:program]) 
+0

Merci beaucoup. Je suis encore un peu nouveau à interroger, donc je dois demander; est-ce que je prends des coups de performance lorsque j'écris quelque chose qui se déplace dans la chaîne d'association? Si oui, auriez-vous des suggestions? –

+0

Tant que vous avez index sur 'courses.program_id' et' course_sessions.course_id', vous devriez être bon. Ce n'est pas un rapport que j'imagine donc je pense que vous êtes en sécurité. – vee

+0

Bon à savoir. Merci. Que voulez-vous dire par "rapport"? –

0

Il est un peu difficile de ce que vous essayez de faire. Votre code suggère que vous voulez:

  • CourseSessions associé à la Program si params[:program] est présent, et
  • Tous CourseSessions si params[:program] n'est pas présent.

Dans ce cas, je crois que vous feriez quelque chose comme:

@sessions = if params[:program] 
    CourseSession.where(course: Course.where(program: Program.find_by(name: params[:program]))) 
else 
    CourseSession.all 
end