# Getting started with Ruby on Rails and Relationships

**URL:** <https://www.ruby-forum.com/t/getting-started-with-ruby-on-rails-and-relationships/105506>\
**Category:** Rails\
**Created:** [May 30, 2007, 3:45pm UTC](https://www.ruby-forum.com/t/getting-started-with-ruby-on-rails-and-relationships/105506 "2007-05-30T15:45:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![revanche](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ac91a4/32.png) [@revanche](https://www.ruby-forum.com/u/revanche)\
**Post date:** [May 30, 2007, 3:45pm UTC](https://www.ruby-forum.com/t/getting-started-with-ruby-on-rails-and-relationships/105506/1 "2007-05-30T15:45:42Z")

</div>

Hello! I’m relatively new to Ruby on Rails, but decided to start  
experimenting with it after looking at how it can simply some rather  
repetitive tasks that I find myself writing with PHP. For the most part,  
I’ve been learning through books and writing code, as expected, and tend  
to plug away at something until I can get it right. Working with  
relationships, however, has proven a bit difficult so I thought I would  
try to solicit some help from anyone willing…

As part of this experiment, I’m building a sample bookstore that has two  
database tables (author, book). Author is setup as has\_many :book, and  
book as has\_one :author

Authors simply has id, firstname, lastname fields while book stores id,  
title, description, author\_id

Inside the book controller, it calls a simple find to display all books  
by a particular author

@results = Book.find(:all, :conditions =\> { :author\_id =\> entry.id})

Entry.id is a numeric value provided by a form on a previous page.

The view page itself is:

\<% @results.each do |result| %\>  
\<%= h(book.title)%\>  
\<%= h(book.description)%\>  
\<% end %\>

All of this works fine.

The question is: Given the setup, how do I display the appropriate first  
and last name of the author for each book? I’ve tried a variety of  
different approaches to no avail, and I’m guessing its just a minor  
error in my methodology.

---

<div class="post-metadata">

**Author:** ![revanche](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ac91a4/32.png) [@revanche](https://www.ruby-forum.com/u/revanche)\
**Post date:** [May 30, 2007, 4:46pm UTC](https://www.ruby-forum.com/t/getting-started-with-ruby-on-rails-and-relationships/105506/2 "2007-05-30T16:46:17Z")

</div>

Hi,

As a side-note, instead of doing  
@results = Book.find(:all, :conditions =\> { :author\_id =\> entry.id})

You can do this:  
@results = Author.find(entry.id).books

Or if entry is already an author instance  
@results = entry.books

This also infers that your relations ships are:  
has\_many :books and belongs\_to :author

On to your actual question, you would want to do:

\<% @results.each do |result| %\>  
\<%= h(book.title) %\>  
\<%= h(book.description) %\>  
\<%= h(book.author.firstname) %\>  
\<%= h(book.author.lastname) %\>  
\<% end %\>

If this gives you problems, check that your relationships are like I  
said  
above:  
has\_many :books on the author model  
belongs\_to :author on the book model

Hope this helps.

Cheers,  
James

---

<div class="post-metadata">

**Author:** ![revanche](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ac91a4/32.png) [@revanche](https://www.ruby-forum.com/u/revanche)\
**Post date:** [May 30, 2007, 4:51pm UTC](https://www.ruby-forum.com/t/getting-started-with-ruby-on-rails-and-relationships/105506/3 "2007-05-30T16:51:49Z")

</div>

If you have a has\_many/belongs\_to relationship between authors and  
books, finding one should give you access to the other.

For example, if author has\_many books, you should be able to do this:

a = Author.find(entry.id) # returns author object with id == entry.id  
@results = a.books # collections of books by the author

Then you should be able to access a.firs\_name and a.last\_name (or  
whatever).

The Rails console is your friend. In a terminal, cd to the root of your  
app, then enter “script/console” (or “ruby script/console”). You can  
enter the lines above (with real numbers, of course) and see the author  
object, and then see if an array of books is returned (assuming you have  
relationships).

Neil H. wrote:

> Hello! I’m relatively new to Ruby on Rails, but decided to start  
> experimenting with it after looking at how it can simply some rather  
> repetitive tasks that I find myself writing with PHP. For the most part,  
> I’ve been learning through books and writing code, as expected, and tend  
> to plug away at something until I can get it right. Working with  
> relationships, however, has proven a bit difficult so I thought I would  
> try to solicit some help from anyone willing…
> 
> As part of this experiment, I’m building a sample bookstore that has two  
> database tables (author, book). Author is setup as has\_many :book, and  
> book as has\_one :author
> 
> Authors simply has id, firstname, lastname fields while book stores id,  
> title, description, author\_id
> 
> Inside the book controller, it calls a simple find to display all books  
> by a particular author
> 
> @results = Book.find(:all, :conditions =\> { :author\_id =\> entry.id})
> 
> Entry.id is a numeric value provided by a form on a previous page.
> 
> The view page itself is:
> 
> \<% @results.each do |result| %\>  
> \<%= h(book.title)%\>  
> \<%= h(book.description)%\>  
> \<% end %\>
> 
> All of this works fine.
> 
> The question is: Given the setup, how do I display the appropriate first  
> and last name of the author for each book? I’ve tried a variety of  
> different approaches to no avail, and I’m guessing its just a minor  
> error in my methodology.

---

<div class="post-metadata">

**Author:** ![revanche](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ac91a4/32.png) [@revanche](https://www.ruby-forum.com/u/revanche)\
**Post date:** [May 30, 2007, 5:04pm UTC](https://www.ruby-forum.com/t/getting-started-with-ruby-on-rails-and-relationships/105506/4 "2007-05-30T17:04:35Z")

</div>

Thank you!

Just one follow-up…

On your recommendation for using  
@results = Author.find(entry.id).books instead of my longer Find query,  
how would you appropriately adjust it if we expanded to check multiple  
fields. Say we created a new field, status.

Would @results = Author.find(entry.id, status).books be appropriate?

James Brooks wrote:

> Hi,
> 
> As a side-note, instead of doing  
> @results = Book.find(:all, :conditions =\> { :author\_id =\> entry.id})
> 
> You can do this:  
> @results = Author.find(entry.id).books
> 
> Or if entry is already an author instance  
> @results = entry.books
> 
> This also infers that your relations ships are:  
> has\_many :books and belongs\_to :author
> 
> On to your actual question, you would want to do:
> 
> \<% @results.each do |result| %\>  
> \<%= h(book.title) %\>  
> \<%= h(book.description) %\>  
> \<%= h(book.author.firstname) %\>  
> \<%= h(book.author.lastname) %\>  
> \<% end %\>
> 
> If this gives you problems, check that your relationships are like I  
> said  
> above:  
> has\_many :books on the author model  
> belongs\_to :author on the book model
> 
> Hope this helps.
> 
> Cheers,  
> James

---

<div class="post-metadata">

**Author:** ![revanche](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ac91a4/32.png) [@revanche](https://www.ruby-forum.com/u/revanche)\
**Post date:** [May 31, 2007, 12:11am UTC](https://www.ruby-forum.com/t/getting-started-with-ruby-on-rails-and-relationships/105506/5 "2007-05-31T00:11:28Z")

</div>

Rails has some magic finders.

To find based on one attribute, like lastName, use  
Author.find\_by\_lastName(‘wibble’)  
To find on two attributes, like lastName and status, use  
Author.find\_by\_lastName\_and\_status(‘wibble’, ‘dead’)

These finders only return one record (the first one they find in the db,  
which may not be the one you expect). To find all records that match the  
criteria, use instead Author. find\_all\_by…

Finding by a record’s id is a special case, which is the one I  
originally presented: Author.find(id), so your construction will not  
work.

If you need to search on more fields (like lastName, firstName, and  
status) you’ll have to use find(:all) with modifiers. That’s a bit much  
to go into here, but is well covered in the Agile Web D. book.  
To give you an idea, a query could be written as

Author.find(:all, :conditions =\> “lastName = ‘wibble’ and status =  
‘dead’”)

BTW, if you are pulling the values for comparison (i.e., ‘wibble’ and  
‘dead’ in my example) from form fields, make sure you understand SQL  
Injection before you do anything like the above query.

[http://www.google.com/search?q=rails+sql+injection](http://www.google.com/search?q=rails+sql+injection)

Neil H. wrote:

> Thank you!
> 
> Just one follow-up…
> 
> On your recommendation for using  
> @results = Author.find(entry.id).books instead of my longer Find query,  
> how would you appropriately adjust it if we expanded to check multiple  
> fields. Say we created a new field, status.
> 
> Would @results = Author.find(entry.id, status).books be appropriate?
