Building a Blog with Ruby on Rails 7, Hotwire, and Turbo - Part 3: Comments, SEO, Analytics, and Deployment

Coding Posted on May 14, 2023
Welcome back to our series on building a blog with Ruby on Rails 7, Hotwire, and Turbo! In this post, we'll focus on adding comments to our blog posts, making the blog SEO-friendly, implementing analytics, and discussing various deployment options, including hosting the blog on AWS using a virtual machine or a Docker container.

Step 1: Adding Comments


To add comments to our blog posts, let's first create a Comment model:

rails generate model Comment post:references body:text name:string email: string
rails db:migrate

Add the association to the Post model (app/models/post.rb):

class Post < ApplicationRecord
  # ...
  has_many :comments, dependent: :destroy
end

And to the Comment model the association to the Post model and add some validations for the comment (app/models/comment.rb):

class Comment < ApplicationRecord
  belongs_to :post
  
  validates :body, presence: true
  validates :name, presence: true
  validates :email,
            presence: true,
            format: {
                      with: URI::MailTo::EMAIL_REGEXP,
                      message: "is not a valid email address"
                    }
end

Let's go ahead and update our 'routes.rb' to include nested routes to create and destroy comments:

Rails.application.routes.draw do
  resources :posts do
    resources :comments, only: [:create]
  end
  # Other routes...
end

This configuration creates the necessary routes for creating and deleting comments, nested under the posts resource. The post_comments_path helper method should now be available, and you can use it in your views and controllers.

Make sure you have a CommentsController with the appropriate create and destroy actions implemented:

class CommentsController < ApplicationController
  before_action :set_post

  def create
    @comment = @post.comments.build(comment_params)
    if @comment.save
      flash[:notice] = "Comment successfully added."
    else
      flash[:notice] = "Failed to add comment."
    end
    redirect_to @post
  end

  private

  def set_post
    @post = Post.find(params[:post_id])
  end

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

Now, let's create a form for adding comments. In app/views/posts/show.html.erb, add the following code below the post content:

<h3>Add a comment:</h3>
<%= simple_form_for [@post, @post.comments.build] do |f| %>
  <%= f.input :body, as: :text, label: "Your Comment" %>
  <%= f.input :name, label: "Your name" %>
  <%= f.input :email, label: "Your email address" %>
  <%= f.button :submit, 'Post Comment', class: 'btn btn-primary' %>
<% end %>

<h3>Comments:</h3>
<%= render @post.comments %>

Then, create a partial for displaying the comments: 'app/views/comments/_comment.html.erb':

<div class="card mt-3">
  <div class="card-body">
    <%= comment.body %>
    <%= comment.name %>
  </div>
</div>

Finally, update the PostsController to handle the comments:

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

Now, our blog supports adding and displaying comments on the posts.

Step 2: SEO-Friendly Blog


To make our blog SEO-friendly, we can start by adding meaningful titles and descriptions to our pages.

In app/views/layouts/application.html.erb, update the <title> tag:

<title><%= content_for?(:title) ? yield(:title) : "My Blog" %></title>

Now, in our app/views/posts/show.html.erb view, you add the following snippet which will set our title meta tag to the title of our blog post using the content_for method:

<% content_for :title, "#{@post.title} | My Blog" %>

To add meta descriptions, update the <head> section in app/views/layouts/application.html.erb:

<head>
  <!-- ... -->
  <%= tag.meta name: "description", content: content_for?(:description) ? yield(:description) : "My Blog - A place to share my thoughts and experiences" %>
</head>

And in our app/views/posts/show.html.erb, set a description:

<% content_for :description, truncate(strip_tags(@post.body), length: 155, separator: ' ', omission: '...') %>

You could also add a description field to your blog post and write a higher quality description for each of your posts, but if you're just getting started and don't want to worry about creating a description for each post, this is better than nothing!

Step 3: Implementing Analytics


For analytics, we'll use Google Analytics. First, sign up for a Google Analytics account and get your tracking code. Then, create a partial called _google_analytics.html.erb in app/views/shared:

<!-- Google Analytics tracking code here -->

Finally, include the partial in app/views/layouts/application.html.erb:

<body>
  <%= render "shared/google_analytics" %>
  <!-- ... -->
</body>

Now, you'll have access to a wide range of analytics data for your blog, such as page views, bounce rates, and user demographics.

Step 4: Deployment Options


Option 1: Deploying to AWS using a Virtual Machine (EC2)

  1. Sign up for an AWS account and create an EC2 instance.
  2. Install Ruby, Rails, and any required dependencies on the EC2 instance.
  3. Set up a database server (e.g., PostgreSQL) on the EC2 instance.
  4. Clone your blog's repository to the EC2 instance.
  5. Configure your Rails app to use the database server and set the RAILS_ENV environment variable to production.
  6. Precompile your assets with rails assets:precompile.
  7. Set up a web server (e.g., Nginx) and configure it to proxy requests to your Rails app.
  8. Set up a process manager (e.g., systemd) to ensure your Rails app is always running.

Option 2: Deploying to AWS using Docker

  1. Sign up for an AWS account.
  2. Install Docker on your local machine.
  3. Create a Dockerfile in your blog's root directory.
  4. Define your app's environment, including Ruby, Rails, and any required dependencies in the Dockerfile.
  5. Set up a database server (e.g., PostgreSQL) using Docker.
  6. Build your Docker image and push it to a container registry (e.g., Docker Hub or AWS ECR).
  7. Create an Amazon ECS (Elastic Container Service) cluster and configure it to run your blog's Docker image.
  8. Set up a load balancer to route traffic to your blog's containers.

Both options have their pros and cons. Deploying to a virtual machine gives you more control over the environment, but requires more manual setup and maintenance. Deploying using Docker makes it easier to manage dependencies and scale your app, but requires familiarity with containerization concepts and tools.

So far in our series on building a blog with Ruby on Rails 7, Hotwire, and Turbo! We've covered creating the blog's foundation, integrating Bootstrap and a rich text editor, adding comments and SEO best practices, implementing analytics, and discussing deployment options. Now you have a functional, attractive, and easily discoverable blog to share your thoughts and experiences. Good luck and happy blogging!

Leave a comment:

Comments (0)