This tutorial describes how to build relationships (one-to-one and one-to-many) between models in a NetBeans Ruby on Rails project.
Contents
- Creating the Sample Database
- Creating the Comment Model
- Migrating the Database
- Defining a Relationship Between the Comment and Post Models
- Modifying the Controller Scaffolding
- Modifying the View to Add Comments
- Displaying the Comments
To complete this tutorial, you need the following software.
| Software or Resource | Version Required |
|---|---|
| NetBeans IDE with Ruby and Rails support | Version 6.0* |
| MySQL database server | Version 5.0 |
| Rails Framework | 1.2.5** |
* If you are using NetBeans IDE 6.1, see the Building Relationships Between Rails Models - NetBeans IDE 6.1 Tutorial.
* This tutorial, which is written for Rails 1.2.5, involves scaffolding. Because scaffolding is not supported in Rails 2.0, you cannot complete this tutorial using Rails 2.0.
Creating the Sample Database
This tutorial builds on the tutorial Creating a Ruby Weblog in 10 Minutes. If you completed that tutorial, you can start with the project that you built when you finished the tutorial and proceed to the next section. Otherwise, download the RubyWebLog.zip file and follow these steps to create the sample database.
Note: This tutorial uses the MySQL database server. See the Installing and Configuring Ruby Support article for information about using a MySQL database server in a Ruby application. The article also describes how to use the Java DB database server instead.
- Open a command window.
- If it has not already been started, start the MySQL database server.
- Type the following command to create the development database and press Enter.
mysqladmin -u root -p create rubyweblog_development
Note: If the root user does not have a required password, omit the -p argument.
Open the rubyweblog project in the IDE.
Note: The first time that you open or create a Ruby project in the IDE, the IDE checks if you have any other Ruby installations in addition to the bundled JRuby software. If you do, the IDE displays a dialog box asking you to select which software to use. Choose JRuby if you want to use the bundled JRuby interpreter, or choose your Ruby installation if you prefer to use it instead. For more information, see Configuring the IDE to Use Your Own Ruby Installation in the Installing and Configuring Ruby tutorial.
If your database requires a password, edit the
To quickly access thedatabase.ymlfile and provide the password under the development configuration. Save the file.database.ymlfile, press Alt+Shift+O (Ctrl+Shift+O on the Mac), typedatabase.ymlin the File Name text field, and press Enter.-
Right-click the rubyweblog node and choose Migrate Database > To Current Version.
This action updates the database to include the posts table and then adds a body field. The Output window indicates when the migration is complete. - Run the application and create a new post.
Creating the Comment Model
This tutorial enhances the rubyweblog project by enabling readers to add comments to a blog post. You begin by creating the Comment model to store instances of readers' comments. The project already includes a Post model for storing instances of blog posts.
-
In the Projects window, expand the rubyweblog node if it is not already expanded, right-click the Models node, and choose Generate.
Type
Comment post_id:integer created_at:datetime comment:textin the Arguments field and click OK.The Rails Generator creates a model named Comment. This model includes the following files:
- app/models/comment.rb. A file that holds the methods for the Comment model. This file is opened in the editing area.
- test/unit/comment_test.rb. A unit test for checking the model.
- test/fixtures/comments.yml. A test fixture for populating the model.
- db/migrate/migrate/003_create_comments.rb. A migration file for altering the structure of the database. This file is version 003 because the project already has two migration files,
001_create_posts.rband002_add_body.rb, which create and modify the posts table.
Migrating the Database
The file that you work with next is the migration file, 003_create_comments.rb.
In the Output window, click the link for the
The file opens to show the self.up method, which creates a table called comments, and the self.down method, which tears the comments table down, as shown in the following code sample:003_create_comments.rbfile.class CreateComments <> This migration creates a comments table with four fields:
id, which contains an integer,post_id, which contains an integer;created_at, which stores the date and time; andcomment, which contains a text description.Right-click the rubyweblog node and choose Migrate Database > To Current Version.
This action updates the the database to include the comments table. The Output window indicates when the migration is complete.
Defining a Relationship Between the Post and Comment Models
You now have two models in the application: the Post model, which creates a new blog post, and the Comment model, which adds a comment to a blog post. Here you define a relationship between the two models so that a comment is associated with a single post, and a post can contain multiple comments.
- Expand the Models node and open
post.rb. -
Add the following
has_manyassociation topost.rb:class Post <>has_many :comments
endThe
has_manymethod indicates that the post can have zero, one, or more comment records associated with it.Typing the trigger hm and pressing Tab expands into the code template has_many :objects.
-
Open Models >
comment.rband add thebelongs_toassociation:class Comment <>belongs_to :post
endThe
belongs_tomethod indicates that a comment can be associated with only one post. By default, ActiveRecord uses thepost_idto associate a comment with the post that has a matchingpost.id.The bt trigger explands to belongs_to :object.
Modifying the Controller Scaffolding
Next you work with the controller, blog_controller.rb, which generates the scaffolding, or the basic interface for creating, reading, updating, and deleting entries in the blog post.
-
Expand Controllers node and open
The controller has all of the scaffold actions, includingblog_controller.rb.index,list,show,new,create,edit,update, anddestroy. -
Modify the
showaction as shown in the following code sample to save the post_id to the flash:def show
The code finds the post associated with the
@post = Post.find(params[:id])
flash[:post_id] = @post.id
endidparameter passed in with the request. It then stores theidin the flash for later use. The flash is similar to an HTTP session, but across a single request. When you put something in the flash, it is available for the next request, and then is gone (hence the name flash). -
Scroll to the end of the
blog_controller.rbfile and add the followingpost_commentaction before the finalendstatement:def post_comment
@comment = Comment.new(
"post_id" => flash[:post_id],
"created_at" => Time.now,
"comment" => params[:comment]['comment']
)
if @comment.save
flash[:notice] = 'Comment was successfully added.'
redirect_to :action => 'show', :id => flash[:post_id]
end
endThe
Comment is an ActiveRecord class, so calling its save method saves the comment record to the database. The message is then put in the flash. The code calls thepost_commentaction is called when the user clicks the Post button to submit a comment. The first block of code gets thepost_idfrom the flash (which is something like 1, 2, or so on) and uses it to find the blog post associated with thatid. The code then creates a new Comment object to be associated with thatpost_id, also consisting of the time created and the actual comment. The Rails framework passes the submitted parameters from the page as a hash (params[:comment]), from which the code pulls out the comment parameter (params[:comment]['comment']).showaction, which loads theshow.rhtmlpage. This page reloads the post and all of its comments, including the new one.
Modifying the View to Add Comments
Here you edit the show.rhtml file, which displays an individual blog entry.
- Expand Views > blog and open
show.rhtml. -
Add the following code at the end of
show.rhtml:
This code produces a form that includes a text input area for writing the comment, and a Submit button labeled Post, as shown in the next figure. The
Comments
<% form_tag :action => 'post_comment' do %>
<%= text_area 'comment', 'comment' %>
<%= submit_tag "Post" %>
<%end %>post_commentaction is called when the form is submitted. - Save your files and run the application.
-
Click a Permalink to view the details of a blog entry. Try adding a comment in the text area, but note that the blog does not yet display comments when you click the Post button.
If your posting is successful, you see a message at the top of the view, as shown in the following figure. In the next steps you add code to collect and display the comments.
Displaying the Comments
The blog does not yet display the comments that a reader adds, so here you fix that problem.
-
In
blog_controller.rb, find theshowaction and insert the followingpost_commentsinstance variable to collect the comments:def show
Because you added the has_many :comments relationship to the Post model, you can access all the comments for a post by calling @post.comments.
@post = Post.find(params[:id])
@post_comments = @post.comments.collect
flash[:post_id] = @post.id
end -
Modify
show.rhtmlby copying and pasting the contents of the following- tag to just after the
Comments
line:- <%= h comment.comment %>
Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %>
<% @post_comments.each do |comment| %>
<% end %>
This code stylizes the comments, displays them in a bulleted list, and includes the date and time that the comment was posted. - <%= h comment.comment %>
-
Choose File > Save All, then refresh your browser.
The comments now appear in the blog in a bulleted list, as shown in the following figure.