所以基本上我有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控制台上提取我的记录:
使用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
答案 0 :(得分:0)
首先,我强烈建议您完整阅读this guide。这是对关联的全面解释,可以帮助您了解正在发生的事情。
但是对于你的情况,首先是控制台。看看错误信息的内容:
NoMethodError: undefined method `Subject' for #<Class:0x007fcf47229980>
这意味着这里有两个问题。
首先,您正在使用各自的课程
正确地找到学生和主题 stud = Student.find(1)
subj = Subject.find(1)
但是当你试图向学生添加一个主题时,你会回到课堂上。您需要使用找到的对象,这些对象现在存储在stud
和subj
中。
此外,由于您的关联是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 ,因为学生有很多科目,因此您必须使用复数形式。