Index of All Lessons

Transcript

Download

Play


Support the Course

There’s no charge for the course, but we greatly appreciate any donations.

Suggested donations:

  • One or two lessons: $5
  • Several lessons $10
  • Entire course: $25 – $50

We hope you’ve found the course to be valuable, and we appreciate any support you care to provide.


Sign Up Now!

If you aren’t already receiving our course lessons via email, sign up now to be sure you don’t miss anything.

Every few days, we’ll send you an email with a link to the next episode, plus a list of additional resources for advancing your knowledge.

There’s no cost and no obligation. And we’ll never share your email address with any third party.


We’ll send you the first lesson right away.


Want to help spread the word? We’d be grateful if you would include a link to the course in your blog, web site, or emails.

Rails Models

14 comments

To listen to the lesson, click the Play button on the left. You can also right-click on the download link to save the mp3 file, or you can subscribe in iTunes (just search for Learning Rails).

To read a transcript of the lesson, click the Transcript link on the left.

The heart of the lesson is the audio; these notes are supplementary. So please listen to the audio, or read the transcript, before making use of these notes.

Resources for Further Study

Any Ruby on Rails book will explain how migrations, models, and associations work. The classic Agile Web Development with Rails does a good job explaining them.

Note that Rails 2.0 provides a slightly simpler syntax for migrations, which we’ve used in our examples, so in most books you’ll see the Rails 1.2 style.

The Rails wiki has an explanation of migrations, but as of this writing it has not been updated for Rails 2.0. The API document provides a less readable but more complete and up-to-date description.

There’s a hand-on tutorial using NetBeans 6.0 that shows how to create migrations and models using the NetBeans IDE.

Code Examples

The user requirements for the example we discuss in this podcast are:

  1. A visitor to the site sees a list of podcasts with their title, description, and a link to an MP3 file
  2. If there is an associated show note for that podcast, a link appears that goes to a page displaying it.
  3. Each podcast is tagged with one or more topic categories which the visitor can see next to the podcast’s other information

Here’s a schematic drawing of the required objects:

The migration that creates the podcast database table reads something like this:

create_table "podcasts" do |t|
    t.string "title" 
    t.string "description" 
    t.string "filename" 
end

The create_table line begins a code block that defines the table. This line provides the shortcut name t, which is referenced in the lines that define the table.

To create a new podcast object, you use a very simple Podcast class and simply type:

episode = Podcast.new

And now you have an instance of the Podcast class, which you’ve named episode. Now, to set its attributes, you can simply write:

episode.title = "Learning Ruby on Rails" 
episode.filename = "learningrails-1.mp3" 
episode.description = "This episode covers..." 

When this code is executed, you’ve created the episode object and filled it with data. Now it takes one more line of code, episode.save, to write the data to the database.

To find an episode by name, you can simply write:

episode = Podcast.find_by_title('Learning Ruby on Rails')

and you’ll get back a podcast object, called episode, with all the information about that podcast.

What about the show notes? We need another migration to define that table, the core of which is simply:

t.text "body" 
t.integer "podcast_id" 

The body field is where we store the text of the show notes. (The column type of “text” instead of “string” tells the database to allow a potentially large amount of text.)

The podcast_id field is how Rails knows what podcast a particular show_notes object is associated with.

To set up the association, you add one line of code to each of the associated models’ classes. The podcast class gets a line that reads:

has_one :show_notes

and the show_notes model gets a line that reads:

belongs_to :podcast

With these two simple additions, you can now write episode.show_notes to access the show notes for a particular episode.

To associate podcasts with categories, we need a join table, whose field definitions are:

t.integer podcast_id
t.integer category_id

With the join table created and the HABTM declarations in the two model files, you can simply write

episode.categories

and you’ll get back an array of category objects, one for each category that is associated with that particular episode.


Add a Comment

Have a comment or question about this lesson? Add it here.






Comments on This Lesson

From: cherrian chin harada       Date: 09/30/08 08:08 AM

Subject: Net Beans 6.0

Hi, I took a look at the ” hands-on tutorial using Net Beans 6.0 for migrations… Do you recommend downloading it? Or just stick to Ruby on Rails? Net Beans seems a little bit over my head since I am total beginner on RoR… I what is your recommendation, do I need this information at this stage?

From: Vitaliy Khudenko       Date: 09/02/08 11:11 AM

Subject: answer to Gurvinder about static pages

Gurvinder, I think these pages are not so static :)

For example, information for AboutUs may change in time (and reality proves it does change). So IMHO the better way is to store changables in DB and give a user (or admin in a common case) to manage this info.

If you really want to place static html-page you can put in your public dir. If Apache (or app router) finds correspondance of incoming URL to a page placed in public dir the controller will even not be invoked and your page will be sent to browser.

From: Michael Slater       Date: 07/16/08 09:09 AM

Subject: Show Notes is singular

Gurvinder, sorry for my poor choice of names. The “shownotes” is the name for a single document (the “show notes” for one show). So confusingly, shownotes is actually a singular reference.

From: Gurvinder       Date: 07/12/08 10:10 AM

Subject: Postcast and Show notes Relationship

I can see above that you have “has_one :show_notes” and “belongs_to :podcast” syntax to make the model aware of the relationship. My question is that why do we have shownotes in plural and podcast in singular. is is one of the Convention over Configuration thing or we can have podcast in plural too.

From: Gurvinder       Date: 07/07/08 09:09 AM

Subject: One more Issue

I am trying to build my First test website with rails on my local machine. The problem is “What should i do about the static pages as Every website has AboutUs, home, etc” and most likely they are all static.

Please Advice.

From: Gurvinder       Date: 07/05/08 09:21 PM

Subject: Rails Models

Thanx for your help in explaining the Model and ORM. I am a new bee for rails and ruby and was not sure where to start from. Can u guid me in the right direction where to go and look for info. about ruby on rails. I have lotsof info. but all is Scattered.

Please advice.

From: Michael Slater       Date: 05/04/08 10:10 AM

Subject: More on join tables and references

Steve, yes, join tables are used only for HABTM relationships. If a model has a has_one or has_many relationship, then the opposite side of the relationship has a belongs_to declaration, and the table for that model stores the foreign key (the id of the record in the other table). Good point on the t.references :podcast option. This is a new Rails 2.0 feature and I’m used to the old way, but this is a potentially cleaner way to specify a foreign key.

From: Michael Slater       Date: 05/04/08 10:10 AM

Subject: Table name

Erwin, you’re correct, that’s a typo. In fact, if the model is called shownote and the table shownotes, which would be the convention, then the code should be has_one :shownote.

From: Michael Slater       Date: 05/04/08 10:10 AM

Subject: Join tables and IDs

Ray, join tables in a HABTM relationship cannot have ids. There is no model associated with the join table, so you can’t reference it directly. You can use has_many :through to use a model table as a join table.

From: Steve       Date: 05/03/08 10:10 AM

Subject: join table clarification

So do I gather from the comments below that the “rule of thumb” for when a join table is required is the “habtm” relationship? You don’t need a join table to associate a singular podcast with its singular shownotes, but you do need a join table to associate multiple podcasts with multiple categories?

Unrelated side note: I found that my brain accepts the “references” keyword in a migration pretty well. So when you write the migration for shownotes, instead of t.integer “podcast_id” one could write t.references :podcast I believe the end result is the same (a database field named “podcast_id”), but it helps clarify that this is a foreign key used in establishing a relationship. Might be helpful to someone.

From: Erwin Odendaal       Date: 05/03/08 05:05 AM

Subject: table name

I presume that “has_one :show_notes” actualy has to be: “has_one :shownotes” since the table’s name is “shownote s” and not “show_notes”?

From: Ray       Date: 05/02/08 08:20 PM

Subject: Join Tables

You make a point that the join table doesn’t get an id of its own, but wouldn’t it be useful to be able to refer to a specific podcast-category relationship? Why did you choose to leave out the id?

From: Michael Slater       Date: 04/26/08 11:11 AM

Subject: Join tables

Pravin, the join table is not automatically generated. You need to create the join table (typically by creating a migration file). The join table has only two columns, one each for the ids of the two tables being joined. It does not have an id column of its own. There is no model that corresponds to the join table.

From: pravin shiraskar       Date: 04/26/08 04:04 AM

Subject: ROR -query related to join table

i don’t understand join table ,it is automatically created when we mention “has_and_belongs_to_many”or we have explicitaly created model for that and why shouldn’t get an ID field of its own,

 

Hosting Provided By

EngineYard.com fully managed Rails hosting

Sponsored By

New Relic Rails Performance Monitoring

FiveRuns Tuneup

Peepcode Screencasts