我一直在寻找,但找不到关于如何删除 HABTM 表中记录的好答案。我想很多人都有同样的要求。
简单地说,我有学生、班级和班级_学生
我希望学生能够放弃课程,或删除已为该学生注册该课程的 HABTM 记录。
对此必须有一个简单的答案。有谁知道它是什么?
我一直在寻找,但找不到关于如何删除 HABTM 表中记录的好答案。我想很多人都有同样的要求。
简单地说,我有学生、班级和班级_学生
我希望学生能够放弃课程,或删除已为该学生注册该课程的 HABTM 记录。
对此必须有一个简单的答案。有谁知道它是什么?
.destroy 或 .delete 在这种情况下不起作用的原因是由于中间表中缺少主键。然而,我们的父对象有一个非常酷的方法,叫做 {other_obj}_ids。它是左表对象、右表对象的 id 集合。这些信息当然是从我们的中间表中填充的。
因此,考虑到这一点,我们有 2 个对象类(学生和类)。如果您不做任何花哨的事情,活动记录魔法通常可以找出中间表,但建议使用 has_many :through。
class Student < ActiveRecord::Base
has_and_belongs_to_many :classes
end
class Classes < ActiveRecord::Base
has_and_belongs_to_many :students
end
我们现在可以用这个设置在中间表方面做什么......
student = Student.find_by(1)
student.classes # List of class objects this student currently has.
student.class_ids # array of class object ids this student currently has
# how to remove a course from the middle table pragmatically
course = Course.find_by({:name => 'Math 101'})
# if this is actually a real course...
unless course.nil?
# check to see if the student actually has the course...
if student.class_ids.include?(course.id)
# update the list of ids in the array. This triggers a database update
student.class_ids = student.class_ids - [course.id]
end
end
我知道回答这个问题有点晚了,但我今晚刚刚经历了这个确切的情况,想在这里分享解决方案。
现在,如果您希望它被表单删除,因为您现在可以看到它是如何实际处理的,只需确保表单输入是嵌套的,这样它就具有以下效果:
你遇到什么麻烦了?你的关系有适当的 :dependent=>:destroy 和 :inverse_of=>[foo] 吗?
假设一个课程有一个课程名称。你可以做:
student.classes.find_by_course_title("Science").delete
所以这里的正确答案是在你看来做这样的事情:
<%= link_to 'Remove', cycle_cycles_group_path(@cycle, cycle), method: :delete %><br />
cycle
来自上面代码所在的块。
@cycle
是来自连接模型控制器的实例变量。
cycle_cycles_group_path
是文件中模型“Cycle”下的嵌套连接表“cycles_groups” routes.rb
:
resources :cycles do
resources :cycles_groups do
end
end
连接模型控制器如下所示:
def destroy
@cycles_group = CyclesGroup.find(params[:id])
@cycle = @cycles_group.cycle
@cycles_group.destroy
puts "cycle: #{@cycle}"
respond_to do |format|
format.html {redirect_to cycle_path(@cycle), notice: 'Training Week was successfully removed!'}
end
end