【49日目】Rails学習日誌 コメントの保存、表示、パーシャル作成、バリデーション、エラーの表示

# 68 コメント保存処理の実装 続き
##  コメントのコントローラーの編集　
binding.pryでコメント入力時のパラメーターを確認
Rails flogによってパラメータが下記のように見やすく表示される

```
  Parameters: 

{

                  "utf8" => "✓",

    "authenticity_token" => "（略）",

               "comment" => {

        "board_id" => "5",

            "name" => "例",

         "comment" => "コメント"

    },

                "commit" => "送信"

}
```

#### ストロングパラメータの設定
保存できるパラメータはboard_id, name, commentのみにする

```ruby:comments_controll.rb
private

def comment_params
  params.require(:comment).permit(:board_id, :name, :comment)
end
```

#### createアクションの作成
ストロングパラメータによって弾かれるかどうかをif文で分岐
分岐した結果、成功をエラーをflashメッセージを用いてリダイレクト先に表示

```ruby:comments_controll.rb
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アクション

```ruby:boards_controller.rb
def show
  @comment = @board.comments.new
end
```

この状態では、新しく作成されたが保存していない空のコメントが含まれてしまう。
=>常にからのコメントがコメント欄に表示されてしまうので修正する。

```ruby:boards_controller.rb
def show
  @comment = Comment.new(board_id: @board.id)
end
```

コメントの初期化の際にboard_idを用いることで、該当のboardのコメントで保存されたコメントのみを表示するようにした。


## viewの作成

```ruby:show.html.erb
<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を作成。

```ruby:_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のパーシャルの呼び出し方を変えれば完了。

```ruby:show.html.erb
<%= render partial: 'comments/form', locals: { comment: @comment } %>
```

#70 コメントモデルへのバリデーション追加
##モデルにバリデーションを作成

```ruby:comment.rb
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を呼び出すように書き換える。

```ruby:_form.html.erb
<%= render 'shared/error_messages' %>
```

commentsにおいても_form.html.erbの先頭にsharedを呼び出すように上記と同じ記載をする。

## エラーの日本語化
config/locales/ja.yml を編集

```ruby:ja.yml
ja:
  activerecord:
    attributes:
      board:
        name: 名前
        title: タイトル
        body: 本文
      comment:
        name: 名前
        comment: コメント
   views:
     pagination:
       first: '最初'
       last: '最後'
       previous: '前'
       next: '次'
       truncate: '...'
```