删除has_and_belongs_to_many表中的记录 - Rails

时间:2013-04-23 15:04:38

标签: ruby-on-rails has-and-belongs-to-many

我一直在寻找,并且找不到如何删除HABTM表中的记录的好答案。我假设很多人都有同样的要求。

简单地说,我有学生,班级和班级_学生

我希望学生能够删除课程,或删除已为该课程签署该学生的HABTM记录。

必须有一个简单的答案。有谁知道它是什么?

4 个答案:

答案 0 :(得分:1)

.destroy或.delete在这种情况下不起作用的原因是由于中间表中缺少主键。但是,我们的父对象有一个名为{other_obj} _ids的非常酷的方法。它是右表对象的左表对象上的id的集合。这些信息当然来自我们的中间表。

因此,考虑到这一点,我们有2个对象类(Student和Classes)。如果你没有做任何花哨的事情,活动记录魔术通常可以找出中间表,但建议使用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

我知道现在回答这个问题有点晚了,但我今晚刚刚经历了这个确切的情况并想在这里分享解决方案。

现在,如果您希望通过表单删除它,因为您现在可以看到它是如何以实际方式处理的,只需确保表单输入是嵌套的,以便它具有以下效果:

答案 1 :(得分:0)

你有什么麻烦吗?你对你的关系有合适的:dependent =&gt;:destroy和:inverse_of =&gt; [foo]吗?

答案 2 :(得分:0)

让我们说一堂课有一个课程名称。你可以这样做:

student.classes.find_by_course_title("Science").delete

答案 3 :(得分:0)

所以这里正确的答案是在你看来做这样的事情:

<%= link_to 'Remove', cycle_cycles_group_path(@cycle, cycle), method: :delete %><br />

cycle来自上面代码所在的块。

@cycle是连接模型控制器的实例变量。

cycle_cycles_group_pathroutes.rb文件中“循环”模型下的嵌套连接表“cycles_groups”:

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