【rails】コメント機能の実装②

※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。

コメント機能の実装をする

前回までで、urlの作成までが完了

routes.rbでルーティングの設定をしたので、controllerでアクションを設定する


空の@commentsを作る

app/controllers/comments.controller.rbのファイルを新たに作る

  1. pathから、「:article_id」を取得(params)できる
  2. Articleから「:article_id」に一致する記事を探す(find
  3. 該当の記事をarticleとする
  4. article.comments.buildにて空の@commentを作る
class CommentsController < ApplicationController
  def new
    article = Article.find(params[:article_id])
    @comment = article.comments.build
  end
end

記事を新規作成するときとやっていることは同じ


コメント投稿フォームを作る

app/views/comments/new.html.hamlのファイルを新しく作る

コメントの投稿をするので、「POST」リクエストのpathを使う


引数に(@comment.article)を書くことで、:article_idを渡せる

  = form_with(model: @comment,
 url: article_comments_path(@comment.article), local: true) do |f|

↓(上部)エラーの表示についてのコード、(下部)フォームの追加をする

.container
  %ul
    - @comment.errors.full_messages.each do |message|
      %li= message

  = form_with(model: @comment, url: article_comments_path(@comment.article), local: true) do |f|
    %div
      = f. label :content, '内容'
    %div
      = f.text_area :content
    = f.submit '保存', class: 'btn-primary'

コメントボタンを追加する

app/views/articles/show.html.hamlを開いて以下を追加する

.container
  = link_to new_article_comment_path(@article) do
    .btn-secondary
      コメントを追加

createアクション

コメントを投稿・保存する

app/controllers/comments.controller.rbを開いて、以下を追加する

  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.build(comment_params)
    if @comment.save
      redirect_to article_path(@article), notice: 'コメントを追加'
    else
      flash.now[:error] = '更新できませんでした'
      render :new
    end
  end

  • @article = Article.find(params[:article_id])
    → POSTリクエストでarticle_idを取得できるので、該当の記事を探してこれる
  • @comment = @article.comments.build(comment_params)
    → パラメーター(comment_params)を@commentに渡す
  • redirect_to article_path(@article), notice: 'コメントを追加'
    → 保存できたら記事詳細ページに戻り、「コメントを追加」のメッセージを表示する
  • flash.now[:error] = '更新できませんでした'
    → 保存できなかったら、「更新できませんでした」のメッセージを表示する
  • render :new
    → newのviewに戻る

セキュリティ強化も忘れずに

コメントのうち、:contentのみを保存する

  private
  def comment_params
    params.require(:comment).permit(:content)
  end

他者がコードをいじってなんでも保存すると困るため、セキュリティ強化しておく


validationの追加

app/models/comment.rbを開く

:contentが未入力はだめだよ」とvalidationを書く

class Comment < ApplicationRecord
  belongs_to :article
  validates :content, presence: true
end

コメント一覧を表示

コメントを取得する

app/controllers/articles.controller.rbを開く

記事詳細ページを表示するため、@articleは最初に取得できている

(showアクションのみ)

  before_action :set_article, only: %i[show]

 # 中略

  private
  def set_article
    @article = Article.find(params[:id])
  end

ここにコメントを追加するので、showアクションに以下を追加する

これだけで@articleに紐づくコメントを取得できる

  def show
    @comments = @article.comments
  end

コメントを表示する

.article
  %h2 コメント一覧
  - @comments.each do |comment|
    .article_comment
      %p= comment.content

railsでは、controllerで定義を書いて、viewでは表示させるだけにする

#DAY22