Deleting join association of has_many :through

I’m trying to use has_many :through, since my join model deserves being
more than just an intersection table.

But when I try to break the association, the break only seems
“temporary”:

Let’s say my two tables are Users and Colors, and the join model is
Favorites.

user = Users.find(1)
user.colors.length

2
c = user.colors.first

#Color:....

user.colors.delete©
user.colors.length

1

Now what do I do here to make this persist?

If I reload my page, user.colors.length == 2 again, and the old color is
still a part of the collection.

I’ve tried reloading the collection after deleting, hoping that would
refresh the associations:

user.colors(true)

but I get 2 again, not 1.

Any ideas?

(I know, I know, I’m a moron…)

Thanks
Jeff

Jeff C. wrote on 10.07.2006 22:12:

I’m trying to use has_many :through, since my join model deserves being
[…]

If I reload my page, user.colors.length == 2 again, and the old color is
still a part of the collection.

I think there is a problem in your table relations.

:through: Specifies a Join Model to perform the query through. Options
for :class_name and :foreign_key are ignored, as the association uses
the source reflection. You can only use a :through query through a
belongs_to or has_many association.

Have you noticed the last sentence?

Markus K. wrote:

:through: Specifies a Join Model to perform the query through. Options
for :class_name and :foreign_key are ignored, as the association uses
the source reflection. You can only use a :through query through a
belongs_to or has_many association.

Have you noticed the last sentence?

I think I’m doing it right.

class User
has_many :favorites
has_many :colors, :through => :favorites
end

class Color
has_many :favorites
has_many :users, :through => :favorites
end

class Favorite
belongs_to :user
belongs_to :color
end

Are you saying I’ve still got the relationships wrong somehow?

def delete_color
color = Color.find(params[:color_id])
user.colors.delete(color) # this works in script/console as expected

at this point, user.colors.length is correct

redirect :action => :show # this will show 2 favorite colors again:
user.colors.length is wrong
end

Rick O. wrote on 11.07.2006 00:34:

You’ll want to delete the Favorite object that joins them.

user.favorites.find_by_color_id(params[:color_id]).destroy

But it should be possible over colors collection, too.
Do you need a user.colors.save afterwards?

Are you saying I’ve still got the relationships wrong somehow?

def delete_color
color = Color.find(params[:color_id])
user.colors.delete(color) # this works in script/console as expected

at this point, user.colors.length is correct

redirect :action => :show # this will show 2 favorite colors again:
user.colors.length is wrong
end

You’ll want to delete the Favorite object that joins them.

user.favorites.find_by_color_id(params[:color_id]).destroy

Markus K. wrote:

Rick O. wrote on 11.07.2006 00:34:

You’ll want to delete the Favorite object that joins them.

user.favorites.find_by_color_id(params[:color_id]).destroy

But it should be possible over colors collection, too.
Do you need a user.colors.save afterwards?

user.colors.save isn’t possible (method missing), but that was a good
clue.

user.save! does the trick.

Thanks Markus!

Jeff

Jeff C. wrote on 11.07.2006 03:33:

clue.

user.save! does the trick.

Can you have a look in the log?
I’m interested in what SQL commands are executed on this save if only
colors association changed and no other user data.
Does it only update the association to colors or everything from user
model?

Thanks
Markus