Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I remove a single HABTM associated item without deleting the item itself?

How do you remove a HABTM associated item without deleting the item itself?

For example, say I have 3 Students that are in a Science class together. How do I remove the Science objects from the StudentsClasses table without deleting the actual Science reference? I'm guessing that Student.Classes.first.delete isn't a good idea.

I'm using JavaScript with drag-and-drop for adding and removing, not check boxes. Any thoughts?

like image 341
humble_coder Avatar asked Jul 07 '09 00:07

humble_coder


People also ask

What is dependent destroy?

If you set the :dependent option to: :destroy, when the object is destroyed, destroy will be called on its associated objects. :delete, when the object is destroyed, all its associated objects will be deleted directly from the database without calling their destroy method.

How to use dependent destroy in Rails?

dependent: :destroy Rails, when attempting to destroy an instance of the Parent, will also iteratively go through each child of the parent calling destroy on the child. The benefit of this is that any callbacks and validation on those children are given their day in the sun.


1 Answers

I tend to use has_many :through, but have you tried

student.classes.delete(science) 

I think needing to have the target object, not just the ID, is a limitation of HABTM (since the join table is abstracted away for your convenience). If you use has_many :through you can operate directly on the join table (since you get a Model) and that lets you optimize this sort of thing into fewer queries.

def leave_class(class_id)   ClassMembership.delete(:all, :conditions => ["student_id = ? and class_id = ?", self.id, class_id) end 

If you want the simplicity of HABTM you need to use

student.classes.delete(Class.find 2) 

Also, calling a model "Class" is a really bad idea. Use a name that isn't part of the core of Ruby!

like image 62
Michael Sofaer Avatar answered Sep 30 '22 07:09

Michael Sofaer