# Has\_many / belongs\_to associations

**URL:** <https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556>\
**Category:** Rails\
**Created:** [September 26, 2008, 6:54am UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556 "2008-09-26T06:54:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [September 26, 2008, 6:54am UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556/1 "2008-09-26T06:54:25Z")

</div>

I have two models, Review and Album.

Album has many reviews, and Review belongs to Album as seen below in  
their respective model files.

class Review \< ActiveRecord::Base  
belongs\_to :album  
end

class Album \< ActiveRecord::Base  
has\_many :reviews  
end

I then added a form to submit reviews for an album:

\<% form\_for @review do |f| %\>

\<% end %\>

In my controller I have :

class ReviewsController \< ApplicationController

def create  
@review=Review.new(params[:review])  
@review.album=@album  
@review.save  
redirect\_to ‘/inventory’  
end

end

i’m not sure that @review.album=@album is the correct syntax, but even  
at the command line when I instantiate an object of type Review and do  
Review.album.title=“GoldDigger”, it says that album is an undefined  
method. The only thing I can think of is that I am missing something  
when I set up the associations.

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [September 26, 2008, 8:08am UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556/2 "2008-09-26T08:08:49Z")

</div>

Jon wrote:

> def create  
> @review=Review.new(params[:review])  
> @review.album=@album  
> thats correct syntax (if @album is a object of Album model)

> i’m not sure that @review.album=@album is the correct syntax, but even  
> at the command line when I instantiate an object of type Review and do  
> Review.album.title=“GoldDigger”, it says that album is an undefined

here ‘Review’ is not a model object ,thats a model class

and always you can’t get any association with any model class (except if  
you write your own code inside of that model class)

first  
@review=Review.find(id)  
unless @review.album  
@review.album=Album.find(id)  
end  
@review.album.title=“GoldDigger”

> method. The only thing I can think of is that I am missing something  
> when I set up the associations.

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [September 26, 2008, 9:39am UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556/3 "2008-09-26T09:39:40Z")

</div>

On Sep 26, 5:53 am, Jon [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> class ReviewsController \< ApplicationController
> 
> def create  
> @review=Review.new(params[:review])  
> @review.album=@album  
> @review.save  
> redirect\_to ‘/inventory’  
> end

The problem you have is that @album is nil, because you haven’t set it  
to anything. It may have been set when you rendered the form, but that  
was a different instance of the controller (quite possibly in a  
different process or even server). You need to have whatever parameter  
in the form you need to be able to retrieve that album, (eg a  
hidden\_field)

Fred

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [September 26, 2008, 4:19pm UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556/4 "2008-09-26T16:19:53Z")

</div>

I tried manually defining @album like so

```
 id=1
 @review=Review.new(params[:review])
 @review.album=Album.find(id)
 @review.save

```

Because of this, I don’t think it’s that @album was not defined. Also  
as I  
brought up before, and I think this is key in showing their is something  
fundamentally wrong in my set up, the association doesn’t even work at  
the  
command line.

Ex:  
a=Album.find(1)  
r=Review.new  
r.album=a

This yields an error that says “NoMethodError: undefined method ‘album=’  
for  
#\<Review:…”

Any insight?

On Fri, Sep 26, 2008 at 12:06 AM, Frederick C. \<

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [September 26, 2008, 6:39pm UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556/5 "2008-09-26T18:39:41Z")

</div>

how do you view the stacktrace? I thin this is the solution to my  
problem…only now migrations is acting funny with me…

On Fri, Sep 26, 2008 at 7:27 AM, Frederick C. \<

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [September 26, 2008, 4:28pm UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556/6 "2008-09-26T16:28:07Z")

</div>

On Sep 26, 3:18 pm, “Jon Liu” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> command line.

Well the full stacktrace is sometimes helpful. Just to be sure, your  
reviews table does have an album\_id column ?

Fred

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [October 13, 2008, 4:20pm UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556/7 "2008-10-13T16:20:25Z")

</div>

Nah, you can set a parent from a child. Dig it:

> > hh = Album.new(:title =\> “Houses of the Holy”, :artist =\> “Led  
> > Zepplin”)  
> > =\> #\<Album id: nil, title: “Houses of the Holy”, artist: “Led  
> > Zepplin”, release\_date: nil, created\_at: nil, updated\_at: nil\>
> 
> > hhr = Review.new(:title =\> “Led Zep’s new album rocks”,  
> > :review\_body =\> “Best. Album. Ever.”)  
> > =\> #\<Review id: nil, title: “Led Zep’s new album rocks”, review\_body:  
> > “Best. Album. Ever.”, album\_id: nil, created\_at: nil, updated\_at: nil\>
> 
> > hh.save  
> > =\> true
> 
> > hhr.save  
> > =\> true
> 
> > hhr.album = hh  
> > =\> #\<Album id: 1, title: “Houses of the Holy”, artist: “Led Zepplin”,  
> > release\_date: nil, created\_at: “2008-10-13 07:13:04”, updated\_at:  
> > “2008-10-13 07:13:04”\>
> 
> > hhr.save  
> > =\> true
> 
> >

-Roy

---

<div class="post-metadata">

**Author:** ![jon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3bc359/32.png) [@jon](https://www.ruby-forum.com/u/jon)\
**Post date:** [October 13, 2008, 9:34am UTC](https://www.ruby-forum.com/t/has-many-belongs-to-associations/149556/8 "2008-10-13T09:34:46Z")

</div>

I’m only guessing here, but I’m thinking maybe that your issue is  
centred around the way rails automagically creates the setter and  
getter methods for associations. From what I’m seeing, I’m guessing  
that has\_many creates attr\_writer methods whereas belongs\_to only  
creates attr\_reader methods. What this means is, album= will not be an  
accessible method, so trying to set the album within a “child”  
association isn’t possible (nor should it be). What you need to do is  
simply set the album\_id. I’ve never tried to create associative data  
the way you are, so I can’t say for sure this is the issue, but I  
think it’s possible. You generally don’t create relationships via  
belongs\_to.

Going the other way, you shouldn’t have any problems though.

Ie.

@album = Album.new( your params )  
@album.reviews = [ Review.new( review1params ),  
Review.new( review2.params ) ]  
@album.save

.etc.etc.

Hope that helps.

Kirk “Torm3nt” Bushell
