More Rails

Recaping where my first Rails post left off, we had a functioning albeit boring application. In this post we’ll expand the applicaton to include the comment table.

More code generation

In the previous post we used Rails to generate a portion of our application:

$ ruby script/generate model Post$ ruby script/generate controller posts

Then used “scaffold :post” in our controller to tell Rails to dynamicly generate CRUD code for us. Now, we need to generate the same scaffold statically instead so that it may be customized. In the /Blog directory:

$ ruby script/generate scaffold Post$ ruby script/generate scaffold Comment

Start up the web server and have a look.

$ ruby script/server

You can access the newly created code from http://localhost:3000/posts and http://localhost:3000/comments. Note that the links have changes from the singular to the plural(need to find out the logic as to why it does this).

Relations

Our Blog application uses a simple one to many relation(one post has many comments). That relation is defined in our data model.Edit app/models/comment.rb:

class Comment < ActiveRecord::Base    belongs_to :post    validates_associated :postend

and in app/models/post.rb

class Post < ActiveRecord::Base    has_many :commentsend

Now we need to tell the view and the controller about the relation. Edit /controllers/posts_controller.rb:

def show    @post = Post.find(@params[:id])    @comments = @post.find_all_in_commentsend

Next we edit the view to include the comments and a link to add a new comment. Edit app/views/posts/show.rhtml adding:

<{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= link_to 'Add Comment', :controller => 'comments', :action => 'new',     :post_id => @post['id'] {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}> |

and

<br /><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104} for comment in @comments {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}=h comment.title {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><br /><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}=h comment.body {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><br /><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104} end {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}>

So that the file now looks like:

<{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104} for column in Post.content_columns {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><p><b><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= column.human_name {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}>:</b> <{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}=h @post.send(column.name) {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}></p><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104} end {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= link_to 'Add Comment', :controller => 'comments',     :action => 'new', :post_id => @post['id'] {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}> |<{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= link_to 'Edit', :action => 'edit', :id => @post {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}> |<{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= link_to 'Back', :action => 'list' {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><br /><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104} for comment in @comments {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}=h comment.title {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><br /><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}=h comment.body {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><br /><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104} end {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}>

The post id is passed to the comment form in the url parameters. We need to tell the comments controller to grab the post id and include it in the "new" form. Edit app/controller/comments_controller.rb adding:

@comment.post_id = @params['post_id']

so the new method looks like:

def new    @comment = Comment.new    @comment.post_id = @params['post_id']end

By default the comment create method(what the new method calls) redirects back to the comments listing. We want it to redirect to the posts listing. Edit the create method so that it looks like:

def create    @comment = Comment.new(@params[:comment])    if @comment.save        flash['notice'] = 'Comment was successfully created.'        redirect_to :controller => 'posts', :action => 'list'    else        render_action 'new'    endend

":controller => 'posts' tells the method to use the posts controller instead of the default comments.
We also need to edit the comments view to include to post id that we pass it. While we are at it, lets change the title form field to a text field instead of a text area. Edit app/views/comments/_form.rhtml adding:

<{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= hidden_field 'comment', 'post_id'  {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}>

and changing:

<{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= text_area 'comment', 'title'  {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}></p>

so the the content is:

<{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= error_messages_for 'comment' {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><p><label for="comment_title">Title</label><br/><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= text_field 'comment', 'title'  {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}></p><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= hidden_field 'comment', 'post_id'  {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}><p><label for="comment_body">Body</label><br/><{9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}= text_area 'comment', 'body'  {9a59223fbbfa3706fcb6f14a9d1c0e9d874b8faac7a72cc56b28c77d373fa104}></p><p><label for="comment_created_on">Created on</label><br/></p><p><label for="comment_updated_on">Updated on</label><br/></p>

Add a new post by visiting http://localhost:3000/posts/new, then click on the "Show" link of the posts listing. You should now see a "Add Comment" link. Add some comments, then view the post again. You should see the comment(s) you posted attached to the post.
More to come.