# Quick question on updating attributes on the join model in a has\_many :through relationship

**URL:** <https://www.ruby-forum.com/t/quick-question-on-updating-attributes-on-the-join-model-in-a-has-many-through-relationship/140584>\
**Category:** Rails\
**Created:** [June 16, 2008, 1:45pm UTC](https://www.ruby-forum.com/t/quick-question-on-updating-attributes-on-the-join-model-in-a-has-many-through-relationship/140584 "2008-06-16T13:45:56Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Morgan\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/57b2e6/32.png) [@Morgan\_G](https://www.ruby-forum.com/u/Morgan_G)\
**Post date:** [June 16, 2008, 1:45pm UTC](https://www.ruby-forum.com/t/quick-question-on-updating-attributes-on-the-join-model-in-a-has-many-through-relationship/140584/1 "2008-06-16T13:45:56Z")

</div>

The question is this: how are you supposed to do it?

I’ve seen a lot of blog posts that say that HM:T has beaten HABTM and  
that  
we can now all easily have data on the join model and go on to show how  
to  
enter that data into the join model but don’t show a recommended way of  
modifying it later.

I’ve checked against a pile of books, too, as well as the AR api and  
Google’s exhaustive collection of blogs. Neither The Rails Way nor Agile  
Web  
Development show an example that I can find.

Obviously this is something really simple that I have missed so if  
someone  
could please post a link to the place where it is actually demonstrated  
that  
would be wonderful.

Taking the example from  
[has\_many :through - New on edge: Magic join model creation](http://blog.hasmanythrough.com/2006/8/19/magic-join-model-creation) if  
you’re  
unsure what I mean:

That automagically creates the join record with the role attribute set  
to

> has\_many :contributors, :through =\> :contributions, :uniq =\> true  
> end

That’s brilliant (although I suspect it will break now because at some  
point  
with\_scope got removed from public so I’m not sure what people suggest  
nowadays).

What if you added another field to contributions? Let’s say, for lack of  
a  
better example, time\_spent. This is how you are supposed to find it, as  
far  
as I can tell:

dave = Contributor.find\_by\_name “Dave”  
book = Book.find\_by\_title “Agile Web D. with Rails”

contribution = Contribution.find\_by\_book\_id\_and\_author\_id book.id,  
dave.id

And then you can now go

contribution.time\_spent = 9.months

But surely there is a way to get that contribution object out of the  
collection proxy? Something like:

contribution = dave.books.proxy\_object(dave.books.first)  
or  
contribution = dave.books.proxy\_objects.first

(Yes, I realise this would be essentially the same thing, but the method  
I  
showed first strikes me as being very non-rails).

So, is there some wonderful resource where this has been demonstrated  
that  
I’ve just missed?

Cheers,  
Morgan.

## –

## Morgan G. - Just Landed General Tel: +34 91 590 2611 removed\_email\_address@domain.invalid

## [http://www.justlanded.com](http://www.justlanded.com) - Helping people abroad! 30 countries, in up to 8 languages, more to come…

---

<div class="post-metadata">

**Author:** ![Morgan\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/57b2e6/32.png) [@Morgan\_G](https://www.ruby-forum.com/u/Morgan_G)\
**Post date:** [June 16, 2008, 6:02pm UTC](https://www.ruby-forum.com/t/quick-question-on-updating-attributes-on-the-join-model-in-a-has-many-through-relationship/140584/2 "2008-06-16T18:02:38Z")

</div>

Is this question too confusing or too obvious to warrant a response from  
somebody?

Morgan.

2008/6/16 Morgan G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Obviously this is something really simple that I have missed so if someone  
> could please post a link to the place where it is actually demonstrated that  
> would be wonderful.

## –

## Morgan G. - Just Landed General Tel: +34 91 590 2611 removed\_email\_address@domain.invalid

## [http://www.justlanded.com](http://www.justlanded.com) - Helping people abroad! 30 countries, in up to 8 languages, more to come…

---

<div class="post-metadata">

**Author:** ![Morgan\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/57b2e6/32.png) [@Morgan\_G](https://www.ruby-forum.com/u/Morgan_G)\
**Post date:** [June 17, 2008, 11:48am UTC](https://www.ruby-forum.com/t/quick-question-on-updating-attributes-on-the-join-model-in-a-has-many-through-relationship/140584/3 "2008-06-17T11:48:38Z")

</div>

Thanks for that.

The basic answer is that you just have to manually find the join model  
and  
then modify that as necessary. Which is what I was doing but which I  
thought  
was silly because hey, this is Rails, there has to be an easier way to  
do  
it. 🙂

Cheers.

2008/6/16 Pardee, Roy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> railscasts on “complex forms” for the gory details.
> 
> HTH,
> 
> -Roy
> 
> * * *
> 
> \*\*

## –

## Morgan G. - Just Landed General Tel: +34 91 590 2611 removed\_email\_address@domain.invalid

## [http://www.justlanded.com](http://www.justlanded.com) - Helping people abroad! 30 countries, in up to 8 languages, more to come…

---

<div class="post-metadata">

**Author:** ![Morgan\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/57b2e6/32.png) [@Morgan\_G](https://www.ruby-forum.com/u/Morgan_G)\
**Post date:** [June 16, 2008, 7:37pm UTC](https://www.ruby-forum.com/t/quick-question-on-updating-attributes-on-the-join-model-in-a-has-many-through-relationship/140584/4 "2008-06-16T19:37:19Z")

</div>

Well, with HM:T, you’ve got an actual model to work with–so you can do  
all the regular things you do w/models–.new them, .update them, etc.  
In a view, you’d do a form\_for & pass in a reference to an instance o  
your join model. The things you’re joining can be represented via say,  
collection\_select’s modifying the respective \<\>\_id fields in  
your join model.

If the goal is allowing create/edit on views devoted to one or both of  
the joined models, you can treat those exactly as if they were just a  
regular has\_many–so, field\_for, w/an appropriately engineered name.  
See the railscasts on “complex forms” for the gory details.

HTH,

-Roy

* * *

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Morgan G.  
Sent: Monday, June 16, 2008 9:02 AM  
To: removed\_email\_address@domain.invalid  
Subject: [Rails] Re: Quick question on updating attributes on the join  
model in a has\_many :through relationship

Is this question too confusing or too obvious to warrant a response from  
somebody?

Morgan.

2008/6/16 Morgan G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

The question is this: how are you supposed to do it?

I’ve seen a lot of blog posts that say that HM:T has beaten  
HABTM and that we can now all easily have data on the join model and go  
on to show how to enter that data into the join model but don’t show a  
recommended way of modifying it later.

I’ve checked against a pile of books, too, as well as the AR api  
and Google’s exhaustive collection of blogs. Neither The Rails Way nor  
Agile Web D. show an example that I can find.

Obviously this is something really simple that I have missed so  
if someone could please post a link to the place where it is actually  
demonstrated that would be wonderful.

## –

## – Morgan G. - Just Landed General Tel: +34 91 590 2611 removed\_email\_address@domain.invalid

## – [http://www.justlanded.com](http://www.justlanded.com) - Helping people abroad! 30 countries, in up to 8 languages, more to come…

–

---

<div class="post-metadata">

**Author:** ![Morgan\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/57b2e6/32.png) [@Morgan\_G](https://www.ruby-forum.com/u/Morgan_G)\
**Post date:** [June 17, 2008, 5:10pm UTC](https://www.ruby-forum.com/t/quick-question-on-updating-attributes-on-the-join-model-in-a-has-many-through-relationship/140584/5 "2008-06-17T17:10:31Z")

</div>

Well, not necessarily–in those railscasts I mentioned, they show how to  
use pseudo-attributes on one of the ‘parent’ models to  
create/update/delete associated instances of a join model. For example,  
here’s a bit of my Project model class (which represents research  
projects) that manages the associations between projects and research  
areas:  
class Project \< ActiveRecord::Base  
has\_many :projects\_research\_areas, :dependent =\> :delete\_all  
has\_many :research\_areas, :through =\> :projects\_research\_areas  
def new\_research\_area\_attributes=(raa)  
raa.each do |ra|  
projects\_research\_areas.build(ra)  
end  
end  
def existing\_research\_area\_attributes=(raa)  
projects\_research\_areas.each do |ra|  
attributes = raa[ra.id.to\_s]  
if attributes  
ra.attributes = attributes  
ra.save  
else  
projects\_research\_areas.delete(ra)  
end  
end  
end  
end # class Project  
Those \*_research\_area\_attributes=() methods get called (as if by magic  
 😉 when the project controller says e.g., Project.new(params[:project])  
and they create/update/delete associated instances of the join model as  
necessary. You direct a given instance of a join model to either the  
new_ or existing\_ version by setting the first argument to fields\_for()  
to the right string. Check out railscasts 73-75 (IIRC) for the full  
story. See especially the updated code posted on the episode 75 page.

HTH,

-Roy

* * *

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Morgan G.  
Sent: Tuesday, June 17, 2008 2:48 AM  
To: removed\_email\_address@domain.invalid  
Subject: [Rails] Re: Quick question on updating attributes on the join  
model in a has\_many :through relationship

Thanks for that.

The basic answer is that you just have to manually find the join model  
and then modify that as necessary. Which is what I was doing but which I  
thought was silly because hey, this is Rails, there has to be an easier  
way to do it. 🙂

Cheers.

2008/6/16 Pardee, Roy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

Well, with HM:T, you’ve got an actual model to work with–so you  
can do all the regular things you do w/models–.new them, .update them,  
etc. In a view, you’d do a form\_for & pass in a reference to an  
instance o your join model. The things you’re joining can be  
represented via say, collection\_select’s modifying the respective  
\<\>\_id fields in your join model.

If the goal is allowing create/edit on views devoted to one or  
both of the joined models, you can treat those exactly as if they were  
just a regular has\_many–so, field\_for, w/an appropriately engineered  
name. See the railscasts on “complex forms” for the gory details.

HTH,

-Roy

* * *

## –

## – Morgan G. - Just Landed General Tel: +34 91 590 2611 removed\_email\_address@domain.invalid

## – [http://www.justlanded.com](http://www.justlanded.com) - Helping people abroad! 30 countries, in up to 8 languages, more to come…

–
