Subscribe
Contact



AddThis Social Bookmark Button

Judging by the number of Ruby on Rails developpers asking themselves this question,
this is the missing example of Rails. (It's not in my Rails reference book, and I've never seen any example on any blog.)

One solution is to create a new model for the association. It schould be the case
if you add attributes to the association (because push_with_attributes is now deprecated).
You can then simply find the association given the ids of your linked object and call destroy.

However, when you don't have any attribute in your liaison, the has_and_belongs_to_many
is nicer to work with. (you don't need a rails model for the liaison.)
Here is a link to the methods has_and_belongs_to_many adds where we can read :


"collection.delete(object, …) - removes one or more objects from the 
collection by removing their associations from the join table.
This does not destroy the objects."

Let's assume we dispose of 2 models 'Post' and 'Category' with a N-N association :

class Post < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

class Category < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

To delete an association (remove a post from a category) you can use this method :

  def remove_post_from_category
     post = Post.find(params[:post][:id])
     category = post.categories.find(params[:category][:id])

     if category
        post.categories.delete(category)
     end

  end

This function will destroy the association but won't destroy the category.

You can also removes all the categories from the posts by using :


collection.clear - removes every object from the collection. 
This does not destroy the objects.

In our example :

 
post.categories.clear

Commentaires :
Zoran , 2008-04-08 22:02:06 UTC
Thank you so much for this!
#1
Jorgegorka , 2008-08-02 13:08:34 UTC
Indeed, it's an important subject that has been sistematically ommited in what should be The Book about rails: Agile web development with rails.

Thank you very much for the post and the clear explanation.
#2
remkade , 2009-06-26 21:38:19 UTC
You can also do this in your model:

before_destroy { |post| post.categories.destroy_all }

Which is much easier I think.
#3
matt , 2010-03-05 07:19:32 UTC
Thanks for the post - deleting associations is also not made very clear by the rails API.

@remkade -- just to add that before_destroy { |post| post.categories.destroy_all} isn't really necessary if you use the :dependent option when you first associate the objects.

Like so:

has_many :feed_entries, :dependent => :destroy # which will destroy all associated objects whenever the feed itself is destroyed.

:dependent also has a bunch of options besides destroy.
#4
Thomas Glasgow , 2010-03-08 21:19:06 UTC
Thank you for the tip, I was just wondering how to remove associations.

Cheers,
#5
Thomas Glasgow , 2010-03-08 21:19:13 UTC
Thank you for the tip, I was just wondering how to remove associations.

Cheers,
#6

Add a comment :





© 2007 Eric Abouaf