简体   繁体   English

如何关联已连接表中的记录? -Ruby on Rails

[英]How Can I Associate Records From A Connected Tables? - Ruby on Rails

So Basically I Have 3 Tables that are associated together and one extra table for the table with each other: Students, Teachers, Subjects and Enrolled Subjects: 因此,基本上,我有3个表关联在一起,并且该表彼此又有一个额外的表:学生,教师,学科和已注册学科:

Here are my migrations: 这是我的迁移:

class CreateStudents < ActiveRecord::Migration[5.0]

  def up
  create_table :students, :id => false do |t|
    t.integer "student_id", :auto_increment => true, :primary_key => true
    t.string "first_name", :limit => 25
    t.string "last_name", :limit => 50
    t.string "email", :default => ' ', :null => false
    t.string "birthday"
    t.string "username", :limit => 25
    t.string "password_digest"
    t.timestamps
  end
  end

class CreateTeachers < ActiveRecord::Migration[5.0]
  def up
  create_table :teachers, :id => false do |t|
      t.integer "teacher_id", :auto_increment => true, :primary_key => true
      t.string "first_name"
      t.string "last_name"
      t.string "email", :default => ' ', :null => false
      t.string "birthday"
      t.string "username", :limit => 25
      t.string "password_digest"
      t.timestamps
    end
  end

class CreateSubjects < ActiveRecord::Migration[5.0]
  def up
    create_table :subjects, :id => false do |t|
       t.integer "subject_id", :auto_increment => true, :primary_key => true
       t.string "subject_name"
       t.timestamps
    end
  end

class CreateEnrolledSubjects < ActiveRecord::Migration[5.0]
  def up
    create_table :enrolled_subjects, :id => false do |t|
      t.integer "subject_id"
      t.integer "teacher_id"
      t.integer "student_id"
    end
  end

So basically: 所以基本上:

  • One students can have many subjects 一个学生可以有很多科目
  • One teacher can have many subjects 一位老师可以有很多科目
  • One students can have many teachers 一个学生可以有很多老师

So I formulated this on my models: 所以我在我的模型上制定了这个:

class Student < ApplicationRecord

  has_many :enrolled_subjects
  has_many :subjects, through: :enrolled_subjects
  has_many :teachers, through: :enrolled_subjects

  has_many :admin_users
  has_secure_password

end

class Teacher < ApplicationRecord

  has_many :enrolled_subjects

  has_many :subjects, through: :enrolled_subjects
  has_many :students, through: :enrolled_subjects
  has_many :admin_users
  has_secure_password

end

class Subject < ApplicationRecord

  has_many :students, through: :enrolled_subjects
  has_many :teachers, through: :enrolled_subjects
  has_many :admin_users

end

class EnrolledSubject < ApplicationRecord
  belongs_to :student
  belongs_to :subject
  belongs_to :teacher
end

Now to put the association on my students, teachers, subjects with my existing records I pull up my records for both on Rails Console: 现在,将关联与我现有的记录一起放在我的学生,老师和科目上,我在Rails Console上同时提取了两个记录:

  • students -> subjects 学生->科目
  • teachers -> subjects 老师->科目
  • students -> teachers 学生->老师

USING RAILS CONSOLE: 使用铁路控制台:

 stud = Student.find(1)
    subj = Subject.find(1)
    stud = Student.Subject << subj

    teacher = Teacher.find(1)
    subj = Subject.find(1)
    teacher = Teacher.Subject << subj

BUT I GOT THE FOLLOWING ERRORS: 但是我遇到了以下错误:

 NoMethodError: undefined method `Subject' for #<Class:0x007fcf47229980>
        from /Users/mac/.rvm/gems/ruby-2.3.1/gems/activerecord-5.0.1/lib/active_record/dynamic_matchers.rb:21:in `method_missing'

Next, I also tried to pull up the student's subjects and teachers (on my views) using the ff: 接下来,我还尝试使用ff调出学生的学科和老师(在我看来):

<% @students.each do |student|%>
<%= student.teachers %>
<%= student.subjects %>
<% end %>

<% @teachers.each do |teacher|%>
<%= teacher.subjects %>
<% end %>

BUT IT ONLY RETURNS ERROR: 但仅返回错误:

ActiveRecord_Associations_CollectionProxy:0x007fed07a7a9a8
  1. How can I associate the existing records on both students and tables (on Rails Console) 如何关联学生和表上的现有记录(在Rails控制台上)
  2. How can I display the records especially the Student's enrolled subjects and their teachers. 我如何显示记录,尤其是学生的入学科目及其老师。 And for teachers, how can I display their subjects. 对于老师,我该如何展示他们的学科。 (via views) (通过视图)

First of all, I highly recommend you read this guide in its entirety. 首先,我强烈建议您完整阅读本指南 It's a thorough explanation of associations and help you understand what's going on. 这是对关联的详尽解释,可以帮助您了解发生了什么。


But for your case, first the console. 但对于您而言,首先是控制台。 Look at what the error message is saying: 查看错误消息在说什么:

NoMethodError: undefined method `Subject' for #<Class:0x007fcf47229980>

This means there are two issues here. 这意味着这里有两个问题。

First, you're finding the student and the subject properly, using their respective classes 首先,您可以使用各自的班级找到合适的学生和科目

 stud = Student.find(1)
 subj = Subject.find(1) 

But then when you try to add a subject to a student, you go back to the class. 但是,当您尝试向学生添加科目时,您将返回课堂。 You need to use the objects you found, which are now stored in stud and subj . 您需要使用找到的对象,这些对象现在存储在studsubj

Furthermore, because your association is has_many , the method name must be plural. 此外,由于您的关联为has_many ,因此方法名称必须为复数形式。 So the third line should look like this: 因此,第三行应如下所示:

stud.subjects << subj

Second, your display. 其次,您的显示。 It's not returning an error, it's returning a Ruby object, which is an active record collection. 它没有返回错误,而是有一个Ruby对象,它是一个活动记录集合。 So you have what you need, but now you should go a step further. 因此,您拥有所需的东西,但是现在您应该走得更远。

The common case is to use the each method on the collection to iterate through it and display what you'd like. 通常的情况是使用集合上的each方法来遍历它并显示您想要的内容。 For example: 例如:

<% @students.each do |student|%>
  <% student.teachers.each do |teacher| %>
    <%= teacher.first_name %>
  <% end %>
<% end %>

But, beware of N+1 query problems . 但是, 请注意N + 1查询问题 If you're going to iterate over objects like this, you should eager load the associated objects . 如果要遍历这样的对象,则应该急于加载关联的对象


And one other thing, as I look through your code. 另一件事,当我浏览您的代码时。 Unless you have a specific and compelling reason to do so, don't change the id field. 除非您有特定而令人信服的理由,否则请勿更改id字段。 With Rails, it's best to follow the convention over configuration approach and let Rails work for you. 使用Rails时,最好遵循约定之上的配置方法,并让Rails为您工作。

您应该在查询中使用stud.subjects ,因为学生有很多科目,因此必须使用复数形式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM