Adding objects to a :through association


#1

So I’m one of those nasty people building a self-referential
habtm-like Association using the funky new :through stuff. This is
about users having friends, so here’s my user.rb:

class User < ActiveRecord::Base
has_many :friendships, :foreign_key => ‘user_id’
has_many :friends, :through => :friendships, :source => :friend
end

And here’s my friendship.rb:

class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => ‘User’, :foreign_key => ‘friend_id’
end

Now, everything is working great as long as I create instances of
Friendship “manually”. Really no problems whatsoever, everything is
working just perfectly.

However, simply moving one user into another user’s list of friends
does not seem to work:

someone.friends << someoneelse # nothing happens

Considering I’m not seeing any notes about collection.<< not working
with :through associations, I’m wondering if this is specific to crazy
self-referential stuff like what I’m doing.

Any hints?

Danke!


http://www.mans.de


#2

Hendrik M. wrote:

So I’m one of those nasty people building a self-referential
habtm-like Association using the funky new :through stuff. This is
about users having friends, so here’s my user.rb:

class User < ActiveRecord::Base
has_many :friendships, :foreign_key => ‘user_id’
has_many :friends, :through => :friendships, :source => :friend
end

And here’s my friendship.rb:

class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => ‘User’, :foreign_key => ‘friend_id’
end

Now, everything is working great as long as I create instances of
Friendship “manually”. Really no problems whatsoever, everything is
working just perfectly.

However, simply moving one user into another user’s list of friends
does not seem to work:

someone.friends << someoneelse # nothing happens

Considering I’m not seeing any notes about collection.<< not working
with :through associations, I’m wondering if this is specific to crazy
self-referential stuff like what I’m doing.

Any hints?

I don’t think you can create a join model record automatically by adding
to a :through association. You have to create the friendship manually.
When you think about it, that makes sense, since the main point of using
a join model is to put other attributes in it. There’s nowhere to
specify those attributes the way you’re trying to do it.

Try doing someone.friendships.create(:friend => friend_user) and see if
that works.


Josh S.
http://blog.hasmanythrough.com


#3

On 3/31/06, Josh S. removed_email_address@domain.invalid wrote:

Try doing someone.friendships.create(:friend => friend_user) and see if
that works.

Yes, that works. I was just confused by the fact that there was no
mention of << not working with :through associations.

When you think about it, that makes sense, since the main point of using
a join model is to put other attributes in it. There’s nowhere to
specify those attributes the way you’re trying to do it.

Yes, I generally agree. However, using :through already has a bunch of
advantages over simple habtm even without “rich” attributes that I
would want to fill manually. In this scenario, the only extra
attribute that I want is created_at, which is set automatically. I was
assuming that AR would create the association model instance
automatically, considering it could easy infer the class name etc.
from the given parameters.

Anyway, user.friendships.create() will work, I was just wondering
really.

Thanks,
Hendrik


http://www.mans.de


#4

Hi Hendrik,

as far as I know, :through associations are read-only.

It makes sense because the model you are going :through is
completely standalone and as such, it may have more than
just the two belongs_to associations you specify.

I.e. the has_many :through directive doesn’t capture enough information
to reliably create the model you are going :through.

Makes sense?

Trevor S.
http://somethinglearned.com


#5

Lets say your association table has a position field – and you need
to order by the position and you also need to be able to update the
position hows that handled?

Chris


#6

It’s not specific to what you’re doing… I had the same problem. I
may have this wrong, but I think :through associations are strictly
read-only. What I’d do:

someone.friendships.create(:friend => someone_else)

This is a little more pedantic, but closer to what’s happening in the
database and perhaps your Friendship model: when you add someone to
your list of friends, you’re creating a field in the friendships
table. HABTM associations might allow you to use the line I’ve quoted?

– Michael D.


#7

Hendrik,
Out of curiosity, what does your schema look like for Friendships?

Hendrik M. removed_email_address@domain.invalid wrote: So I’m one of those nasty people
building a self-referential
habtm-like Association using the funky new :through stuff. This is
about users having friends, so here’s my user.rb:

class User < ActiveRecord::Base
has_many :friendships, :foreign_key => ‘user_id’
has_many :friends, :through => :friendships, :source => :friend
end

And here’s my friendship.rb:

class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => ‘User’, :foreign_key => ‘friend_id’
end

Now, everything is working great as long as I create instances of
Friendship “manually”. Really no problems whatsoever, everything is
working just perfectly.

However, simply moving one user into another user’s list of friends
does not seem to work:

someone.friends << someoneelse # nothing happens

Considering I’m not seeing any notes about collection.<< not working
with :through associations, I’m wondering if this is specific to crazy
self-referential stuff like what I’m doing.

Any hints?

Danke!


http://www.mans.de