How to retrieve attributes from HABTM?


#1

We have tables Users and Communities linked by has_an_belongs_to_many.
The join table Communities_Users has additional fields [ is_active,
is_blocked, join_date] etc. These are populated using
@user.push_with_attributes(:is_active => true,…).
Later on how do we update or retrieve the attributes in the link table
for a given user or a community with doing it explicitly using SQL?

Thanks,
Yash


#2

Why don’t you create a model for the join table?


#3

Yash <yashgt@…> writes:

We have tables Users and Communities linked by has_an_belongs_to_many.
The join table Communities_Users has additional fields [ is_active,
is_blocked, join_date] etc. These are populated using
user.push_with_attributes(:is_active => true,…).
Later on how do we update or retrieve the attributes in the link table
for a given user or a community with doing it explicitly using SQL?

Without creating a separate model for the join table, there appears to
be no
easy way to update a HABTM join’s attributes. I usually have to delete
the
associated object and add it back in again with the changed atttributes.

Retrieval is OK. community.users should provide you with the join table
attributes merged into the users attributes. If have any fields named
the same
thing, I think they get clobbered.

Or you could create your own model for the join table. However this
involves its
own problems. Do you make a fake autonumber/serial primary key field for
the
table then? If you do, Rails should work fine, although you’ve lost the
purity
of the join table in the process.

If you choose leave your table with a composite primary key of (user_id,
community_id) (or whatever), Rails will have a very hard time dealing
with it.
Update and destroy methods will not work (I usually override the update
method
in the model with a custom SQL statement). Record inserts will work,
although
Rails automatically tries to go get the ID field from the last inserted
row (in
PostgreSQL, by selecting the current value from an appropriately named
sequence). But since the PK is not an autonumber/serial, there is no
sequence,
so Rails fails. I get around this by setting the (nonexistant) ID
attribute
before I save it (model_record[‘id’] = some_bogus_value). That seems to
fool
Rails well enough.

Really, the HABTM support in Rails is pretty lame. It’s been one of the
most
frustrating aspects of ActiveRecord for me. Unfortunately, given how
zealous DHH
is about every table having an ID primary key, I don’t see this getting
fixed
anytime soon.


#4

I’ll chime in on going with the join model approach. It just works
better with Rails. I’m doing a multi-part essay on my blog about things
you can do with them, so instead of repeating myself I’ll refer you
there :slight_smile:

http://blog.hasmanythrough.com

–josh

KW wrote:

Yash <yashgt@…> writes:

We have tables Users and Communities linked by has_an_belongs_to_many.
The join table Communities_Users has additional fields [ is_active,
is_blocked, join_date] etc. These are populated using
user.push_with_attributes(:is_active => true,…).
Later on how do we update or retrieve the attributes in the link table
for a given user or a community with doing it explicitly using SQL?


#5

Yash wrote:

We have tables Users and Communities linked by has_an_belongs_to_many.
The join table Communities_Users has additional fields [ is_active,
is_blocked, join_date] etc. These are populated using
@user.push_with_attributes(:is_active => true,…).
Later on how do we update or retrieve the attributes in the link table
for a given user or a community with doing it explicitly using SQL?

As the others have said this is a good case for a separate domain model
say Membership. See the Agile book page 241

_tony


#6

you could also use sql to update the join table:

ActiveRecord::Base.connection.execute(sql)

should work fine. However, if you really see yourself using and
interacting with the join table, go the :through route…


#7

is this the same issue? although i’m too newby to know if it’s just
me, i’ve run into problems with HABTM as well

http://dev.rubyonrails.org/ticket/1031