Laragon

Adding Comments

This guide walks you through creating a Comment model, setting up one-to-many associations with articles, building a comment form, handling form submissions, displaying comments, and adding timestamps using Rails best practices.

Most blogs allow readers to interact with content by posting comments. This guide walks through implementing comment functionality in a Rails application.

Designing the Comment Model

Comment Attributes

A comment typically has:

  • Association with an article
  • Author name
  • Body text

Generating the Model

Run this command to generate the Comment model:

rails generate model Comment author_name:string body:text article:references

This creates:

  • A migration file
  • The comment model (comment.rb)

Migration Setup

The generated migration (db/migrate/[timestamp]_create_comments.rb) includes:

class CreateComments < ActiveRecord::Migration[5.1] 
  def change                                        
    create_table :comments do |t|                   
      t.string :author_name                         
      t.text :body                                  
      t.references :article, foreign_key: true      
      t.timestamps                                  
    end                                             
  end                                               
end

Run the migration:

rake db:migrate

Model Relationships

One-to-Many Relationship

  • One article has many comments
  • Each comment belongs to one article

Model Files

app/models/comment.rb:

class Comment < ActiveRecord::Base
  belongs_to :article
end

app/models/article.rb (add this):

class Article < ActiveRecord::Base
  has_many :comments
end

Console Testing

Test the relationship in Rails console:

article = Article.first
article.comments # => []
comment = article.comments.new
comment.author_name = "Example Author"
comment.body = "Great article!"
comment.save

# Alternative one-step creation:
article.comments.create(author_name: "Another", body: "Nice!")

Displaying Comments

Show Template

Add to app/views/articles/show.html.erb:

<h3>Comments (<%= @article.comments.size %>)</h3>
<%= render partial: 'articles/comment', collection: @article.comments.reverse %>

Comment Partial

Create app/views/articles/_comment.html.erb:

<div>
  <h4>Comment by <%= comment.author_name %></h4>
  <p class="comment"><%= comment.body %></p>
  <% if comment.created_at %>
    <p>Posted <%= distance_of_time_in_words(comment.article.created_at, comment.created_at) %> later</p>
  <% end %>
</div>

Comment Form

Controller Setup

In ArticlesController#show:

@comment = Comment.new
@comment.article_id = @article.id

Form Partial

Create app/views/comments/_form.html.erb:

<h3>Post a Comment</h3>
<%= form_for [ @article, @comment ] do |f| %>
  <p>
    <%= f.label :author_name, "Your Name" %><br/>
    <%= f.text_field :author_name %>
  </p>
  <p>
    <%= f.label :body, "Your Comment" %><br/>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit 'Submit' %>
  </p>
<% end %>

Routing

Update config/routes.rb:

resources :articles do
  resources :comments
end

Comments Controller

Generate the controller:

rails generate controller comments

Implement create in app/controllers/comments_controller.rb:

def create
  @comment = Comment.new(comment_params)
  @comment.article_id = params[:article_id]
  
  if @comment.save
    redirect_to article_path(@comment.article)
  else
    render :new
  end
end

private

def comment_params
  params.require(:comment).permit(:author_name, :body)
end

Final Steps

  1. Test the complete workflow
  2. Commit your changes:
git add .
git commit -m "finish blog comments feature"
git push

Now your blog has fully functional commenting!