はじめに
文章を投稿するときに、空文字にしてエラーをバリデーションで検知、それをエラーメッセージとして表示させたい。
前提
No | 項目 | 内容 |
---|---|---|
1 | OS | Mac |
2 | Ruby | 2.6.3 |
3 | rails | 6.0.4 |
実装
1. バリデーションを実装
まず最初に、投稿内容にvalidationをかける。項目は空欄と5000文字以上。
validates :content, presence: true, length: { maximum: 5000 }
2. コントローラーの設定
postコントローラーのnewアクションに、current_userが投稿したオブジェクト(@post) を渡す。これがエラーメッセージの情報を格納するための箱となってくれる。
def new
@post = current_user.posts.build
end
3. テンプレートを設定
次に、newアクションのデフォルトで呼び出されるnewテンプレートに、エラーメッセージ表示させるパーシャルを追加する。
<div class="row">
<%= form_with(model: @post) do |f| %>
# エラーメッセージ表示
<%= render 'shared/error_messages', object: f.object %>
# ここから下は今回のテーマとは関係ないため無視して良い
# 投稿内容記載フォーム
<div class="field">
<%= f.text_area :content, placeholder: "記事を書いて..." %>
# Postリクエスト
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<% end %>
</end>
newテンプレートの投稿フォームを未入力で送信したときにvalidationによってエラーが発生し、その情報が@postに格納される。
それが、error_messagesパーシャルに渡されて、エラー内容表示をするための材料として扱われる。
このとき、object: f.objectによって材料を渡している。変数objectに対して、f.objectを渡す。
筆者はこのobjectに情報を渡し方を間違えて表示がうまくできなかった。@postをPost.newとしてしまい、そこには当然エラーメッセージは格納されないため、エラー表示が出なかった。
渡されたオブジェクトを使って描画していく。
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
さいごに
今回行った実装手順を書きにまとめる。
- バリデーションをかける。
- そのエラー内容をコントローラーの@postに格納する。
- テンプレートに渡された変数にform_withを使い、@post.object(エラー内容情報)をエラーメッセージ用パーシャルに渡す。@post.objectのエラー内容や、エラー個数を呼び出してレンダリングする。