High Leverage Rails
Introduction
Introduction to this course
Why use Ruby on Rails
Why use SQLite
Ruby on Rails + SQLite
Powering Your App with SQLite
Creating tables
Timestamps
Column types
Typeof
Ruby types
Creating table introduction
Creating table advanced
Inserting data
Updating data
Upserting data
Reading data
Virtual columns
Enums
Introduction to JSON
Indexing JSON
JSON table functions
Building a Modern Rails Application
Creating a new Rails application
Installing Solid Queue
Installing Solid Cache
Installing Solid Cable
Dockerfile
Application overview
Authentication
Base styles
Registration
Scaffolding posts
Polishing posts
Scaffolding comments
Polishing comments
Polishing models
Polishing controllers
Creating new post
Updating post
Reviewing MVP
Tagging posts
Custom tags
Friendly URLs
Full text search
Deploying & Operating Your App
Backups
Check Litestream locally
Verifying backups
Deployment options
Deploying with Hatchbox
Deployment constraints
Vertical scaling
Database access
Migrations
Locked video

Please purchase the course to watch this video.

Video thumbnail
Building a Modern Rails Application
Polishing comments

Full Course

$
129
$179
USD, one-time fee
This course came at the perfect time. I’ve recently gotten back into Rails after an 18-year hiatus, and this was a perfect refresher and shows just how much you can accomplish with Rails right out of the box.
Garrett Winder
Garrett Winder

Move fast and fix things

Application monitoring that helps developers get it done.

Rails hosting made simple

Deploy apps to servers that you own and control.

Summary

Learn how to customize the comments feature in a Rails application by nesting comments under posts and enforcing authentication. This video covers updating routes, controllers, and views to streamline user interactions while implementing authorization rules for security. By the end, you'll have a structured comment system that ensures only authenticated users can create, edit, or delete comments.

Video Transcript

Now that we have posts fully set up, it's time to customize the comments feature to fit the needs of Lorem News. Just like with posts, I wrote down a basic set of rules for how comments should behave within our application:

  • Users can comment on posts, but comments are not independent—each comment belongs to a specific post.
  • Comments can be publicly read, just like posts.
  • Only authenticated users can create, edit, or delete comments.
  • Only the user who created a comment can edit or delete it.

There are several changes we need to make to the Rails-generated scaffold to enforce these rules properly.

Updating the Routes for Nested Comments

Currently, the comments resource is a top-level resource, meaning it exists independently, just like posts. However, comments should always be associated with a post, so we need to nest the comments resource inside posts.

Let’s update our routes file to reflect this:

resources :posts do
  resources :comments, only: [:create, :edit, :update, :destroy], shallow: true
end

This setup ensures:

  • Comments are created within the context of a post.
  • No need for unnecessary routes like index or show.
  • Shallow routing keeps URLs cleaner—while create requires a post ID (/posts/:post_id/comments), actions like edit, update, and destroy can be accessed directly via /comments/:id.

Modifying the Comments Controller

Since comments depend on posts, we need to update the CommentsController accordingly.

Remove Unnecessary Actions Since comments are not standalone resources, we can delete the following actions: index, show, and new.

class CommentsController < ApplicationController
  before_action :set_post, only: %i[:create]
  before_action :set_comment, only: %i[:edit, :update, :destroy]

  # No need for index, show, or new
  def create
    @comment = @post.comments.new(comment_params.merge(user: Current.user))

    if @comment.save
      redirect_to @post, notice: "Comment was successfully created."
    else
      render "posts/show"
    end
  end

  private
  
  def set_post
	@post = Post.find(params.expect(:post_id))
  end

  def set_comment
    @comment = Comment.find(params[:id])
  end

  def comment_params
    params.expect(comment: [ :body ])
  end
end
  • The create method now ensures that the comment’s post and user are set automatically rather than relying on form inputs.
  • We removed index, show, and new since comments are always accessed through a post.

Updating the Comment Form

Since comments are now nested under posts, we need to update the form to reflect that.

<%= form_with(model: [@post, comment]) do |f| %>
  <div>
    <%= f.label :body, "Add a comment:" %>
    <%= f.text_area :body, rows: 3 %>
  </div>
  <div>
    <%= f.submit "Post Comment" %>
  </div>
<% end %>
  • The form now correctly associates each comment with its post by passing [@post, comment].
  • We removed the post_id and user_id fields since these are handled automatically in the controller.

Displaying Comments on the Post Page

Since comments belong to posts, we should render them directly on the post’s show page (posts/show.html.erb):

<%= render "comments/form", comment: @post.comments.new %>

This ensures comments are only visible under their respective posts. We need to ensure that we can see the collection of comments on the Post show page too.

<%= render @post.comments %>

Fixing Authentication and Authorization

Currently, any user can see the comment form, even if they’re not logged in. Let’s fix that.

<% if Current.user.present? %>
  <%= render "comments/form", post: @post, comment: @post.comments.new %>
<% end %>

We need to make a tweak to our authentication controller to ensure that a logged in user can see the form, by adding a :resume_session before action. Now only authenticated users can see the comment form.

Next, we need to ensure only the comment’s creator can edit or delete it by modifying CommentsController:

before_action :set_comment, only: [:edit, :update, :destroy]

def set_comment
  @comment = Comment.find(params.expect(:id))
  raise NotAuthorized unless @comment.user == Current.user
end
  • Only the user who created the comment can modify it.
  • Unauthorized users will receive an error instead of being able to make changes.

At this point, we have:

  • Nested comments under posts for cleaner URLs.
  • Ensured only authenticated users can create, edit, or delete comments.
  • Made the UI more intuitive by rendering comments on the post page.
  • Added security checks to prevent unauthorized actions.

Next, we’ll polish the UI further and refine the styling and user experience to make interactions smoother.