# Newbie trying to teach himself relationships (dangerous)

**URL:** <https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090>\
**Category:** Rails\
**Created:** [November 3, 2007, 12:00am UTC](https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090 "2007-11-03T00:00:42Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nevyn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/9de053/32.png) [@Nevyn](https://www.ruby-forum.com/u/Nevyn)\
**Post date:** [November 3, 2007, 12:00am UTC](https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090/1 "2007-11-03T00:00:42Z")

</div>

Hi Guys,

I am trying to learn ruby on rails as well as computer programming in  
general. I am a little confused about relationships.

I want to create a ‘has and belongs to many’ relationship by making my  
books taggable. I don’t know what the difference between a tag vs  
category.

I want to add categories to my book application and have them  
displayed just like you see on blogs but I don’t get it. Be nice  
please, I am very new.

Whenever somebody creates a new book object I want them to be able to  
assign the book to a category and display it, if a category doesn’t  
exist yet, I want the book object to create it. I also want books to  
be able to perform CRUD operations and be able to add/remove/etc…  
books from categories.

I am really lost on how to do it. I am starting to understand the ruby  
syntax well enough, but I don’t get the logic.

Can someone please give me an example on how I do this and explain it  
to me like I’m a total newbie?  
Or in the least, provide me with links explaining how you would do  
this.

Thank you very much for your time and helping.

Nevyn

---

<div class="post-metadata">

**Author:** ![Nevyn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/9de053/32.png) [@Nevyn](https://www.ruby-forum.com/u/Nevyn)\
**Post date:** [November 3, 2007, 12:33am UTC](https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090/2 "2007-11-03T00:33:26Z")

</div>

> Hi Guys,
> 
> I am trying to learn ruby on rails as well as computer programming in  
> general. I am a little confused about relationships.
> 
> I want to create a ‘has and belongs to many’ relationship by making my  
> books taggable. I don’t know what the difference between a tag vs  
> category.

…

> Can someone please give me an example on how I do this and explain it  
> to me like I’m a total newbie?  
> Or in the least, provide me with links explaining how you would do  
> this.

This may help:

[http://mboffin.com/stuff/ruby-on-rails-data-relationships.png](http://mboffin.com/stuff/ruby-on-rails-data-relationships.png)

---

<div class="post-metadata">

**Author:** ![Nevyn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/9de053/32.png) [@Nevyn](https://www.ruby-forum.com/u/Nevyn)\
**Post date:** [November 3, 2007, 2:54am UTC](https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090/3 "2007-11-03T02:54:11Z")

</div>

First of all, welcome to Rails and to programming. You have no  
apologies to make, all of us had to start somewhere, and getting  
advice from this community is a great way to start.

As to your question about book categories/tags: There are multiple  
ways that you can implement categories in an application, depending on  
your problem domain.

The simplest is a one-to-many relationship. In this case a Category  
would contain many Books, but an individual Book would be listed under  
a single Category. If that scenario works for you then go with that.  
It’s makes the implementation quite a bit easier.

If you need to allow an individual Book to be listed under multiple  
categories, then you would need to model a many-to-many relationship.  
There are two ways to accomplish this, again depending on your use  
case. You could associate them using a has-and-belongs-to-many (HABTM)  
as long as you have no need to expose additional attributes within the  
join table used to categorize books. Using this type of relationship  
has some disadvantaged if you are planning to use a RESTful controller  
style. What I mean by this is that you would need custom actions on  
the categories or books controllers (or both) in order to maintain the  
relationship. The other option is to use a has\_many :through  
relationship where the join table would be exposed as a resource with  
its own CRUD operations that can be used to maintain the relationship.  
Maybe you could call that joining resource something like  
Categorization. When you want to associate a Book to a Category you  
would use a “create” action to do that. To disassociate them you would  
use a “destroy” action.

Another design pattern I’ve used in the past had the concept of  
subcategories, where the Category object was represented by a “tree  
structure.” In the Rails world this could be handled by using the  
acts\_as\_tree plugin. This would incorporate a “reflexive”  
relationship. That’s just a fancy way to sat that it is a relationship  
that wraps back to the same table. These types of relationships can be  
either one-to-many or many-to-many. In the former case the tree is  
represented by a single table containing a foreign key back to a  
different row in the same table. In the latter case there would be two  
tables where the second acts as a join between two different rows of  
the first table. Note: this is a fairly advanced technique, but I just  
wanted you to be aware of it.

About your question of categories vs. tags. I would not consider the  
type of categories here as tags. These are two separate concepts.  
Categories are sort of “hard linked” relationships for organizing  
books within your store. Tags are generally more free form and  
something intended for the user’s domain. At least from the “social  
networking” point of view. There are some nice plugins available to  
help you with tagging resources. Look for acts\_as\_taggable for more  
details.

---

<div class="post-metadata">

**Author:** ![Nevyn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/9de053/32.png) [@Nevyn](https://www.ruby-forum.com/u/Nevyn)\
**Post date:** [November 3, 2007, 5:42pm UTC](https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090/4 "2007-11-03T17:42:16Z")

</div>

Robert, thank you very much for taking the team to help me! It’s nice  
to see that there are kind people on this list!

I decided to use the one-to-many approach.

Book belongs\_to :category  
Category has\_many :books

This seems to be okay, I have been playing around in irb and really  
confusing myself yet again, so maybe you can help. I’m sure this is a  
simple problem for most, but I just have not’ been able to UNDERSTAND  
yet. I am close though…

I now have my relationship in place, but what if I want to find all  
the book by a certain category.  
I’m confused on how that works. I am reading up on it, but I don’t  
understand it.

Would I put a method in my BookController that finds all categories?  
But how do I display the book in a view.

To make it simple,

I want to find all books by category name. Do I need to create a new  
route for this?

I want the URL to be like [http://foo.com/categories/book\_name](http://foo.com/categories/book_name) and then  
list all the books that are in that category.

I keep getting nil objects and no method errors when I try. I am now  
grasping at straws since I seem to have confused myself terribly.

Thanks again.

---

<div class="post-metadata">

**Author:** ![Nevyn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/9de053/32.png) [@Nevyn](https://www.ruby-forum.com/u/Nevyn)\
**Post date:** [November 4, 2007, 10:16am UTC](https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090/5 "2007-11-04T10:16:41Z")

</div>

You can put your method in any controller you like. In this case lets  
say Book controller. The method is going to be like this:

def find\_books\_for\_category  
all\_books = Book.find\_all\_by\_category\_id(params[:id])

# another way would be :

all\_books = Category.find(params[:id]).books  
end

For the url you can define it in you routes.rb file within config  
folder like  
map.connect ‘categories/:id’, :controller =\> ‘book’, :action =\>  
‘find\_books\_for\_category’

but the url you will get will be some thing like  
[http://foo.com/categories/5](http://foo.com/categories/5)  
however you can get something like [http://foo.com/categories/5-book\_name](http://foo.com/categories/5-book_name)

if you will add this in your book model  
def to\_param  
“#{id}-#{book\_name}”  
end

I don’t think its a good idea to use a url like  
[http://foo.com/categories/book\_name](http://foo.com/categories/book_name)  
because multiple books can have the same name which will give you  
unpredicted results.

---

<div class="post-metadata">

**Author:** ![Nevyn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/9de053/32.png) [@Nevyn](https://www.ruby-forum.com/u/Nevyn)\
**Post date:** [November 4, 2007, 9:20pm UTC](https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090/6 "2007-11-04T21:20:31Z")

</div>

> I don’t think its a good idea to use a url like [http://foo.com/categories/book\_name](http://foo.com/categories/book_name)  
> because multiple books can have the same name which will give you  
> unpredicted results.

Well, this is just an app for me to learn rails. I can do it by  
params[:id] but I am more curious to know how to find all books by  
category name, more for my own knowledge than practical design. I’ve  
tried but I still can’t figure it out.

thanks so much for everything this far, you guys have been very helpful!

---

<div class="post-metadata">

**Author:** ![Nevyn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/9de053/32.png) [@Nevyn](https://www.ruby-forum.com/u/Nevyn)\
**Post date:** [November 5, 2007, 8:45am UTC](https://www.ruby-forum.com/t/newbie-trying-to-teach-himself-relationships-dangerous/119090/7 "2007-11-05T08:45:05Z")

</div>

then considering you have an attribute called category\_name in your  
Category model, you can do it like this

all\_books =  
Category.find\_by\_category\_name(params[:category\_name]).books
