Rails 7 「Rails 入門」 コメントを検証するための推奨される方法は何ですか?
概要
レールは初めてです。よろしくお願いします。 コメント検証を含む公式 Rails 7 ガイドに記載されているブログの機能を拡張しようとしています。 これはプロジェクト コードの github リポジトリ リンクです。 コメントに検証を追加し、無効なフォームを送信した後にフロントエンドにエラーメッセージを表示する正しい方法は何ですか?
設定 ubuntu - 22.04 RVM-1.29.12 ルビー - 3.1.4p223 レール - 7.0.4.3
現在、コメントモデルにこれらの検証を追加すると、検証が機能しません。空のコメントフォームを送信すると、投稿ページにリダイレクトされるだけです。
/app/models/comment.rb
class Comment < ApplicationRecord
belongs_to :post
validates :author, presence: true
validates :body, presence: true
end
また、comments_controllerでコメントの保存を処理しようとしました。ただし、コメントは空の :author フィールドと :body フィールドとともに保存されます。
/app/controllers/comments_controller.rb
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.build(comment_params)
if @comment.save
redirect_to @post
else
render @post, status: :unprocessable_entity
end
end
/app/views/comments/_form.html.erb
<%= form_with model: [@post, @post.comments.build] do |form| %>
<div class="mb-3">
<%= form.label :author, class: 'form-label' %><br>
<%= form.text_field :author, class: 'form-control', placeholder: 'John Doe' %>
</div>
<div class="mb-3">
<%= form.label :body, class: 'form-label' %><br>
<%= form.text_area :body, class: 'form-control', rows: 3 %>
</div>
<div class="mb-3">
<%= form.submit 'Add comment', class: 'btn btn-outline-primary' %>
</div>
<% end %>
ここに私が達成したい視覚化がいくつかあります(開発ツールを通じていくつかのHTMLを追加しただけです)。最初のスクリーンショット - コメント フォームを送信する前にページを投稿し、ページをクリーンアップするだけです。 2 番目のスクリーンショット (私がハイブしたいもの) - 空の作成者フィールドと本文フィールドを持つコメント フォームを送信した後の同じページ。
最初のスクリーンショット
2 番目のスクリーンショット (これは私が望むコメントフォームです)
解決策
保存が失敗した場合は、CommentsController クラスの作成メソッドに次の 2 つの変更を加えます。
投稿を再取得する必要がある理由は、投稿の表示ビューが (/posts/show.html.erb 内で) 再レンダリングされるときに、表示ビュー内の <%= render @post.comments %> 行が投稿のすべてのコメントをリストします。失敗時にレンダリングする前に再フェッチしない限り、新しい「失敗」コメントが含まれます。
これが解決策の最初の部分です。次に、コメント フォームの上にエラー メッセージを表示し、コメント フォームの作成者と本文に元の値を再入力します。これを実現するには、/posts/show.html.erb で次のことを行う必要があります。
まず、コメント フォーム (コメントの追加
セクション) をレンダリングするには、次の手順を実行します。
<%= 部分レンダリング: ‘コメント/フォーム’、ローカル: { コメント: @comment } %>
これにより、コメントが使用できるようにコメント部分ビュー (/comments/_form.html.erb) に渡されます。以下は、目的を達成する部分ビューのサンプルです。
<p style="color: red"><%= comment ? comment.errors.full_messages.to_sentence : nil %></p>
<%= form_with model: [ @post, @post.comments.build ] do |form| %>
<p>
<%= form.label :author %><br>
<%= text_field_tag 'comment[author]', comment&.author %>
</p>
<p>
<%= form.label :body %><br>
<%= text_area_tag 'comment[body]', comment&.body %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
セーフ ナビゲーション演算子 (&.) は、オブジェクトが nil かどうかを確認します。したがって、フォームに有効なコメントがある場合 (再レンダリングが失敗した場合にのみ当てはまります)、元のデータが表示されます。そうでない場合、フィールドは空になります。 & も同様に使用できます。構文はエラー メッセージに表示されますが、各プロパティに追加する必要があるため、代わりに「長い」バージョンを残しました。
コメント モデルの検証のいずれかが失敗すると、エラー メッセージが表示され、失敗したコメントの元の内容がそれぞれのフィールドに再入力されます。
コメントエラーの例
最後の「クリーンアップ」として、部分的な @post に直接アクセスするのではなく、ローカルの投稿を /comments/_form.html.erb に渡すことを検討できます。