68 コメント保存処理の実装 続き
コメントのコントローラーの編集
binding.pryでコメント入力時のパラメーターを確認
Rails flogによってパラメータが下記のように見やすく表示される
Parameters:
{
"utf8" => "✓",
"authenticity_token" => "(略)",
"comment" => {
"board_id" => "5",
"name" => "例",
"comment" => "コメント"
},
"commit" => "送信"
}
ストロングパラメータの設定
保存できるパラメータはboard_id, name, commentのみにする
private
def comment_params
params.require(:comment).permit(:board_id, :name, :comment)
end
createアクションの作成
ストロングパラメータによって弾かれるかどうかをif文で分岐
分岐した結果、成功をエラーをflashメッセージを用いてリダイレクト先に表示
def create
# コメントオブジェクトを作成
# フォームに入力されたパラメータで初期化
comment = Comment.new(comment_params)
# コメントの保存。保存前にバリデーションチェック
# 保存の可否によってif文で分岐
if comment.save
flash[:notice] = 'コメントを投稿しました' #flashでリダイレクト先に一時的にメッセージを渡す
redirect_to comment.board
else
# 以下はRails5.1以降専用
# コメントが保存できなかった場合入力したコメントオブジェクトとエラーメッセージのリストを返す。
# コメントオブジェクトの中身をリダイレクト先のフォームに戻したり、エラー表示は今後作る
flash[:comment] = comment
flash[:error_messages] = comment.errors.full_messages
redirect_back fallback_location: comment.board # redirect_backで一つ前の画面に戻るようリダイレクト
end
end
69 コメントの表示
showの問題を修正
修正前のshowアクション
def show
@comment = @board.comments.new
end
この状態では、新しく作成されたが保存していない空のコメントが含まれてしまう。
=>常にからのコメントがコメント欄に表示されてしまうので修正する。
def show
@comment = Comment.new(board_id: @board.id)
end
コメントの初期化の際にboard_idを用いることで、該当のboardのコメントで保存されたコメントのみを表示するようにした。
viewの作成
<div class="p-comment__list">
<div class="p-comment_listTitle">コメント</div>
<%= render @board.comments %>
# 特定のモデル(comment)のオブジェクトのリスト(comments)をrenderの引数に渡した場合、自動的にモデル名(comment)のviewが使用される。
# オブジェクトの数だけ繰り返しviewがレンダリングされる。
# 今回のrenderの対象は「comments」なので、/app/views/comments/_comments.html.erbがオブジェクトの数レンダリングされる
</div>
コメント表示用のパーシャルの作成
/app/views/commentsを作成し、_comment.html.erbを作成。
<div class="p-comment__item">
<p><%= simple_format(comment.comment) %></p> # simple_formatヘルパーで改行を<br>タグに変換してくれる
<div class="p-comment__bottomLine">
<span><%= comment.name %></span>
<span><%= comment.created_at.to_s(:datetime_jp) %></span> #以前作った日本語時刻表示
</div>
</div>
リファクタリング
commentを投稿するためのviewはcommentsディレクトリの下にある。
しかし、_comment_formはboardsディレクトリの下にある。
=>役割的にcommentsディレクトリ配下にあるべきなので修正する。
_form.html.erb としてcomments配下にコピーした上で、shownのパーシャルの呼び出し方を変えれば完了。
<%= render partial: 'comments/form', locals: { comment: @comment } %>
70 コメントモデルへのバリデーション追加
モデルにバリデーションを作成
validates :name, presence: true, length: { maximum: 10 }
validates :comment, presence: true, length: { maximum: 1000 }
エラーメッセージを作成
comments_controller.rbのcreateアクションのelse以下がバリデーションエラーの表示になる
以前作成した掲示板のcreate時のエラーメッセージを流用する
app/views/sharedディレクトリを作成
_error_messages.html.erbを作成
<% if flash[:error_messages] %>
<div class="alert alert-danger">
<ul>
<% flash[:error_messages].each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
各viewのエラー呼び出しを編集
まずはboardsから
こちらではすでに作成している_form.html.erb内にエラー表示の部分があるため、sharedを呼び出すように書き換える。
<%= render 'shared/error_messages' %>
commentsにおいても_form.html.erbの先頭にsharedを呼び出すように上記と同じ記載をする。
エラーの日本語化
config/locales/ja.yml を編集
ja:
activerecord:
attributes:
board:
name: 名前
title: タイトル
body: 本文
comment:
name: 名前
comment: コメント
views:
pagination:
first: '最初'
last: '最後'
previous: '前'
next: '次'
truncate: '...'