このページの内容は以下のリポジトリに1日遅れで反映されます(記事執筆前に前日分をコミットしています)。
https://github.com/hkob/hkob_blog
はじめに
Rails Tips の 67 回目です。Rails ガイドでは、コメントのエラーに対する対応がされていません。これは index の中にフォームを書いているために、エラー対応ができないためでした。せっかくなのでその部分を対応するようにしたいと思います。
9.2 パーシャルのフォームをレンダリングする
Rails ガイドでは、show に直接 form を書き込んでいました。二度手間になるので、この部分を部分テンプレートにします。また、そのあとで追加するコメント一覧の部分も部分テンプレートで表示します。app/views/articles/show.html.haml
は以下のようになりました。
- content_for :title do - @page_title = @article.title %p= @article.body %ul %li= lotfp edit_article_path(@article) %li= destroy_lotfp article_path(@article), Article %h2 Comments = render partial: "articles/comments/comment", collection: @comments %h2 Add a comment: = render "articles/comments/form"
articles/comments/_comment.html.haml
は以下のようになります。
- %i[commenter body].each do |attr| %p= t_ars Comment, attr %p= comment.send attr
同様に articles/comments/_form.html.haml
は以下のようになります。ガイドでは、その場で @article.comments.build
で新規オブジェクトを作成していますが、これだと既存のエラーが発生したオブジェクトが捨てられてしまうので、あくまで @comment
というインスタンス変数にしています。こちらは後でコントローラで作成します。
= form_with model: [@article, @comment] do |form| %table %thead %tr %th 項目 %th 内容 %tbody - %i[commenter body].each do |attr| %tr %td= form_label_and_error form, @comment, attr %td - case attr - when :commenter = form.text_field attr - else = form.text_area attr, rows: 10, cols: 80 %tr %td{colspan: 2}= form.submit
ここで利用する @comments
と @comment
は articles_controller
の show で取得します。
def show @comments = @article.comments.order_created_at_desc @comment = @article.comments.build end
order_created_at_desc
は comment.rb 内の scope
で作成します。先に comment_spec.rb
でテストをしておきます。降順確認は以下で解説しています。
describe "Comment クラスについて" do context "order_bar_desc" do subject { described_class.order_created_at_desc } it_behaves_like "降順確認", Date.today + 1, ->(o) { o.created_at } end end
このテストを通すために、comment.rb
に scope
を追加します。
scope :order_created_at_desc, -> { order(created_at: :desc) }
おわりに
これでとりあえず form まで表示されることまで確認しました。少し長くなったので、コントローラのテストと実装は明日に回します。