【发布时间】:2014-11-05 18:00:12
【问题描述】:
在 Rails ( 4.1.5 / ruby 2.0.0p481 / win64 ) 应用程序中,我在 Student 和 Course 之间有一个多对多的关系,以及一个代表关联的连接模型 StudentCourse,它有一个名为“started”的附加属性",默认设置为"false"。
我还在由 student_id 和 course_id 组成的连接表中添加了一个索引,并对其设置了唯一检查,就像这样
t.index [:student_id, :course_id], :unique => true, :name => 'by_student_and_course'
现在我看到关联是通过以下任一方式创建的:
Student.first.courses.create(:name => "english")
或
Course.first.students << Student.first
这很好,我想这是预期的行为。
我所关注的是获取和设置“started”属性的正确方法。 从其他模型而不是直接从连接模型访问该属性时,我看到了一种奇怪的行为。
s = Student.create
c = Course.create(:name => "english")
s.student_courses.first
=> | "英文" |假 | # (表示为实用表)
s.student_courses.first.started = true
=> | "英文" |真的 |
s.save
=> 是的
好吧,看起来它已经被保存了,但是当我抢劫 ak 时:
StudentCourse.first
=> | 1 | 1 |假 |
因此,如果我遍历学生嵌套属性,则它设置为 true,但在连接模型中它仍然为 false。我也尝试过“重新加载!”但这没有什么区别,他们会保持自己不同的价值。
如果事情变得如此糟糕以至于值实际上并没有持久化,我应该被告知而不是在保存时获得“真实”,因为否则后果会有多糟糕?我在这里错过了什么?
无论如何,如果我尝试直接修改join模型上的“started”属性,我会遇到另一种问题:
StudentCourse.first.started = true
StudentCourse Load (1.0ms) SELECT "student_courses".* FROM "student_courses" LIMIT 1 => 是的
StudentCourse.first.started
=> 错误
它没有改变!
StudentCourse.find_by(:student_id => "10", :course_id => "1").started = true
=> 是的
StudentCourse.find_by(:student_id => "10", :course_id => "1").started
=> 错误
和以前一样..我尝试:
StudentCourse.find(1).started = true
ActiveRecord::UnknownPrimaryKey:模型 StudentCourse 中表 student_courses 的未知主键。
然后用:
sc = StudentCourse.first
sc.started = true
=> 是的
sc
=> | 1 | 1 |真的 |
看起来不错,但保存时:
sc.save
(0.0ms) 开始交易
SQL (1.0ms) UPDATE "student_courses" SET "started" = ?在哪里 "student_courses"."" 为 NULL [["started", "true"]] SQLite3::SQLException:没有这样的列:student_courses。:更新 "student_courses" SET "开始" = ? WHERE "student_courses"."" 为空 (1.0ms) 回滚事务 ActiveRecord::StatementInvalid: SQLite3::SQLException:没有这样的列:student_courses。:更新 "student_courses" SET "开始" = ? WHERE "student_courses"."" 是 NULL 来自 C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/sqlite3-1.3.9-x64-mingw32/lib/sqlite3/database.rb:91:in `初始化'
所以我认为这一切都与没有主键有关 连接表?
但我不太确定如何使用它以及这是否代表 我试图解决的案例的良好做法?
另外,如果这是问题所在,为什么我没有收到相同的警告 当我救了学生之后在这里
s.student_courses.first.started = true,如示例所示 上面?
代码
student.rb
class Student < ActiveRecord::Base
has_many :student_courses
has_many :courses, :through => :student_courses
end
course.rb
class Course < ActiveRecord::Base
has_many :student_courses
has_many :students, :through => :student_courses
end
student_course.rb
class StudentCourse < ActiveRecord::Base
belongs_to :course
belongs_to :student
end
schema.rb
ActiveRecord::Schema.define(version: 20141020135702) do
create_table "student_courses", id: false, force: true do |t|
t.integer "course_id", null: false
t.integer "student_id", null: false
t.string "started", limit: 8, default: "pending", null: false
end
add_index "student_courses", ["course_id", "student_id"], name: "by_course_and_student", unique: true
create_table "courses", force: true do |t|
t.string "name", limit: 50, null: false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "students", force: true do |t|
t.string "name", limit: 50, null: false
t.datetime "created_at"
t.datetime "updated_at"
end
end
create_join_table.rb(连接表的迁移)
class CreateJoinTable < ActiveRecord::Migration
def change
create_join_table :courses, :students, table_name: :student_courses do |t|
t.index [:course_id, :student_id], :unique => true, :name => 'by_course_and_student'
t.boolean :started, :null => false, :default => false
end
end
end
【问题讨论】:
-
请列出您对 Student、Class 和 StudentClass 的模型定义。
-
@nikkon226 用代码更新问题
-
StudentCourse 架构是
id, course_id, student_id, started, created_at, updated_at? -
添加到问题 schema.rb 和用于连接表创建的迁移代码。
标签: ruby-on-rails ruby activerecord many-to-many nested-attributes