Ruby on rails Rails:如何正确修改和保存联接表中记录的值
我想了解为什么在Rails 4(4.2.0)中,我在处理联接表中的数据时会看到以下行为:Ruby on rails Rails:如何正确修改和保存联接表中记录的值,ruby-on-rails,ruby,many-to-many,associations,rails-activerecord,Ruby On Rails,Ruby,Many To Many,Associations,Rails Activerecord,我想了解为什么在Rails 4(4.2.0)中,我在处理联接表中的数据时会看到以下行为: student.student_courses 返回给定用户的所有相关课程记录 但以下内容将保存更改 student.student_courses[0].status = "attending" student.student_courses[0].save 而这不会 student.student_courses.find(1).status = "attending" student.studen
student.student_courses
返回给定用户的所有相关课程记录
但以下内容将保存更改
student.student_courses[0].status = "attending"
student.student_courses[0].save
而这不会
student.student_courses.find(1).status = "attending"
student.student_courses.find(1).save
为什么会这样,为什么这两种方法的工作方式不同,第一种方法是正确的吗?
student\u courses
是一种ActiveRecord::Relation
,基本上是一种键=>值
存储。find
方法只适用于模型
学生。学生课程[0]
和学生。学生课程。find(1)
是微妙不同的事情
当你说student.student\u courses
时,你只是在ActiveRecord::Relation
中构建一个查询。一旦对该查询执行了需要访问数据库的操作,就会检索数据。在您的情况下,某个东西正在调用[]
或查找
。当您调用[]
时:
student.student_courses[0]
您的学生
将执行底层查询并将所有学生课程
隐藏在某个地方。您可以通过查看以下内容来了解这一点:
> student.student_courses[0].object_id
# and again...
> student.student_courses[0].object_id
# same number is printed twice
但如果调用find
,则每次只检索一个对象,并检索一个新对象:
> student.student_courses.find(1).object_id
# and again...
> student.student_courses.find(1).object_id
# two different numbers are seen
这意味着:
student.student_courses[0].status = "attending"
student.student_courses[0].save
也就是说:
c = student.student_courses[0]
c.status = "attending"
c.save
鉴于:
student.student_courses.find(1).status = "attending"
student.student_courses.find(1).save
是这样的:
c1 = student.student_courses.find(1)
c1.status = "attending"
c2 = student.student_courses.find(1)
c2.save
当您使用
find
版本时,您在完全不同的对象上调用status=
和save
,并且由于您save
的对象中实际上没有任何更改,因此save
没有任何用处。您是否期望Student.Student\u courses.find(1)
引用状态
变量?编辑:通过编辑修复。是的,已修复。。(但这只是一个输入错误,不是问题的根源)看起来find
通过FinderMethods
模块包含在ActiveRecord::Relation
中:但它确实像数组方法一样查找并返回记录。唯一的问题是,在执行查找(1)时无法保存数据。保存我仍然很困惑。。为了更广泛地理解这一点,你能给我指个地方吗?谢谢,基本上,这取决于我是否向数据库发出新查询,对吗?但是我怎么知道什么会触发DB请求,什么不会呢?在你的回答中,你说stud.student\u courses[0]
将执行查询并将其隐藏在某个地方,这没关系,因为我知道当我执行stud=student.find(10)
时,它都被保存到stud.student\u courses[N]
中,因此现在每个student\u课程都不需要额外的查询。但是,我又如何知道哪些方法仍然会再次执行新的DB查询呢?背后的理由是什么?你能给我指一些医生吗?谢谢!还有一个小问题。。。如果在初始my查询后更改了DB数据,会发生什么情况?student.student\u课程[1]
是否仍保留我的“旧”数据,或者它是否反映了发生的“实时”变化?在Rails中处理这种情况的常用方法是什么?我已经看到了#reload的使用,但我仍然在质疑自己,在我的#reload之后,数据库又发生了一次非常迅速的变化,这会带来什么后果……我发现大多数Rails文档都是毫无用处的,对不起。调用find
始终会命中数据库。对整个关联执行某些操作会命中数据库并隐藏结果,以便使用相同的数组。没有锁定,除非你自己做,这样你就不会知道背后发生的变化,基本假设是不会发生。