はじめに
確認画面の情報は既にいくつも公開されていますが、編集の際の確認画面に関しては、あまり見当たらなかったため記事にしました。
開発環境
- Rails 6.0.3.1
- Ruby 2.6.8
やりたいこと
既に新規登録/編集機能があるアプリにて、それぞれ投稿の前に確認画面を挟みたい。
今回は、title
とcontent
というカラムを持つBlog
モデルに関して実装していく。
新規投稿の確認画面
Controllerの実装
新規投稿の際のcontrollerは以下のようになります。
def new
@blog = Blog.new
end
def confirm
@blog = Blog.new(blog_params)
render :new if @blog.invalid?
end
def create
@blog = Blog.new(blog_params)
if params[:back] || !@blog.save
render :new
else
redirect_to blogs_url, notice: "#{@blog.title}を投稿しました。"
end
end
new
とcreate
アクションは、Railsのチュートリアル等のまんまです。
追加点として、
-
confirm
アクションを定義し、内部で値が不正だったら、new
にレンダリングする -
create
アクションでは、params[:back]
という値があるとき、もしくはblogが保存できなかったとき、new
にレンダリング、そうでない時は一覧画面へリダイレクトする。この時のparams[:back]
は後ほど、view側で設定。
の上記2点です。
Viewの実装
ビューでは新しくapp/views/blogs/confirm.html.erb
を作成します。
中身は、ブログの各カラムが確認できるshowのようなものと、投稿/修正するボタンを含めたフォームになっています。
<h1>
<%= @blog.title %>
</h1>
<p>
<%= @blog.content %>
</p>
<%= form_with model: @blog, local: true do |f| %>
<%= f.hidden_field :title %>
<%= f.hidden_field :content %>
<%= f.submit "投稿する" %>
<%= f.submit "修正する", name: "back" %>
<% end %>
ポイントとしては、
- 修正に戻るsubmitボタンに、name属性として
back
を指定する - title, contentをhidden_fieldとしてユーザーから編集できない形で再度サーバー側に送るようにする
の2点です。確認画面から編集内容をサーバーに送る方法としては、hidden_fieldで値を隠す方法、sessionを用いる方法の2つが挙げられますが、パスワードや管理者権限等の値を取り扱っていないため、今回はhidden_fieldを用いています。
sessionを用いる方法に関しては、こちらのサイトなどをご参考ください。
続いて、app/views/blogs/new.html.erbのformの送り先もconfirmに設定し直します。
<%= form_with model: @blog, url: confirm_blogs_url(@blog), local: true do |f| %>
<div>
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div>
<%= f.label :content %>
<%= f.text_area :content %>
</div>
<%= f.submit "投稿する" %>
<% end %>
formタグのurlにて、送り先が変更されている点にご注意ください。
routes.rbの編集
最後に、ルーティングを設定して、実装完了です。
ルーティングは、resourcesを用いている場合は、以下のようになります。
resources 'blogs' do
collection do
post 'confirm'
end
end
編集の確認画面
ここまでで新規投稿の確認画面に関して、実装してきましたが、ここから編集の確認画面を実装していきます。
と言っても、被っている点が非常に多いので、説明は簡潔にしていきたいと思います。
Controllerの実装
def edit
@blog = Blog.find(params[:id])
end
def edit_confirm
@blog = Blog.find(params[:id])
@blog.attributes = blog_params
render :edit if @blog.invalid?
end
def update
@blog = Blog.find(params[:id])
if params[:back] || !@blog.update(blog_params)
render 'edit'
else
redirect_to blogs_url, notice: "#{@blog.title}を編集しました。"
end
end
ほとんど新規投稿の際のアクションと同様ですが、attributesメソッドを用いて、値の更新をしていることにご注意ください。また、編集の性質上、idが必要なため新規投稿と編集でconfirmを違うアクションとして設定しています。
Viewの実装
Viewもほとんど新規投稿と同じです。
<h1>
<%= @blog.title %>
</h1>
<p>
<%= @blog.content %>
</p>
<%= form_with model: @blog, local: true do |f| %>
<%= f.hidden_field :title %>
<%= f.hidden_field :content %>
<%= f.submit "投稿する" %>
<%= f.submit "修正する", name: "back" %>
<% end %>
<%= form_with model: @blog, url: edit_confirm_blog_url(@blog), local: true do |f| %>
<div>
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div>
<%= f.label :content %>
<%= f.text_area :content %>
</div>
<%= f.submit "投稿する" %>
<% end %>
urlの違いにご注意ください。
routes.rbの編集
最後に、ルーティングを設定して、実装完了です。
編集の際にはidが必要なため、memberの中に追加します。
resources 'blogs' do
collection do
post 'confirm'
end
member do
patch 'edit_confirm'
end
end
参考記事に関して
公式ガイド等の他に以下の記事を参考に、執筆させていただきました。