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

时间:2017-01-29 14:27:44

标签: mysql ruby-on-rails ruby activerecord

所以基本上我有3个关联在一起的桌子和一个额外的桌子彼此:学生,教师,科目和注册科目:

以下是我的迁移:

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

基本上是这样的:

  • 一名学生可以有很多科目
  • 一位老师可以有很多科目
  • 一名学生可以有很多老师

所以我在我的模特身上制定了这个:

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

现在要将我的学生,教师,科目与我现有的记录联系起来,我在Rails控制台上提取我的记录:

  • 学生 - &gt;受试者
  • 老师 - &gt;受试者
  • 学生 - &gt;教师

使用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

但我得出以下错误:

 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'

接下来,我还尝试使用ff来提升学生的科目和老师(根据我的观点):

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

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

但它只会回复错误:

ActiveRecord_Associations_CollectionProxy:0x007fed07a7a9a8
  1. 如何关联学生和表格上的现有记录(在Rails控制台上)
  2. 如何显示记录,尤其是学生注册的科目及其老师。对于教师,我如何展示他们的科目。 (通过意见)

2 个答案:

答案 0 :(得分:0)

首先,我强烈建议您完整阅读this guide。这是对关联的全面解释,可以帮助您了解正在发生的事情。

但是对于你的情况,首先是控制台。看看错误信息的内容:

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

这意味着这里有两个问题。

首先,您正在使用各自的课程

正确地找到学生和主题
 stud = Student.find(1)
 subj = Subject.find(1) 

但是当你试图向学生添加一个主题时,你会回到课堂上。您需要使用找到的对象,这些对象现在存储在studsubj中。

此外,由于您的关联是has_many,因此方法名称必须为复数。所以第三行应该是这样的:

stud.subjects << subj

其次,你的显示器。它没有返回错误,它返回一个Ruby对象,这是一个活动的记录集合。所以你有你需要的东西,但现在你应该更进一步。

常见的情况是在集合上使用each方法迭代它并显示您想要的内容。例如:

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

但是,要小心N + 1个查询问题。如果你要迭代这样的对象,你应该eager load the associated objects

另外一件事,我查看你的代码。除非您有特定且令人信服的理由,否则请勿更改id字段。使用Rails,最好遵循约定优于配置方法,让Rails为您工作。

答案 1 :(得分:0)

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