Ruby
Rails

Scaffoldに確認画面を追加する


概要

scaffoldで生成したフォームに確認画面を追加します。

新規作成(new)の確認画面作成は見かけるのですが、編集(edit)に対するものは無く、割と悩んだので作成しました。

コントローラのcreateメソッドとupdateメソッド内で、確認画面の表示とDBへの保存を振り分けるようにしました。


準備

まずはscaffoldを作成します。

rails generate scaffold book title:string author:string


バリデーションの追加

フォームに対するバリデーションを追加します。確認画面に移る前に入力値に問題が無いか検証します。


book.rb

class Book < ApplicationRecord

validates :title, :author, presence: true
end


コントローラ

新規作成時のcreateメソッドと編集時のupdateメソッドをそれぞれ変更します。


新規作成

バリデーションで問題なく、confirmボタンが押された時は確認画面を開きます。

backボタンが押された時は新規作成画面に戻ります。


books_controller.rb

  # POST /books

# POST /books.json
def create
@book = Book.new(book_params)

respond_to do |format|
if @book.valid? && params[:confirm]
format.html { render :new_confirm }
elsif params[:back]
format.html { render :new }
elsif @book.save
format.html { redirect_to @book, notice: 'Book was successfully created.' }
format.json { render :show, status: :created, location: @book }
else
format.html { render :new }
format.json { render json: @book.errors, status: :unprocessable_entity }
end
end
end



編集

基本は新規作成と同じです。

scaffold自動生成の@book.updateを使わず、assign_attributesを使ってDBに保存しないようにすることで、確認画面を表示できるようにしています。


books_controller.rb

  # PATCH/PUT /books/1

# PATCH/PUT /books/1.json
def update
@book.assign_attributes(book_params)

respond_to do |format|
if @book.valid? && params[:confirm]
format.html { render :edit_confirm }
elsif params[:back]
format.html { render :edit }
elsif @book.save
format.html { redirect_to @book, notice: 'Book was successfully updated.' }
format.json { render :show, status: :ok, location: @book }
else
format.html { render :edit }
format.json { render json: @book.errors, status: :unprocessable_entity }
end
end
end



ビュー

scaffold生成の作成画面を変更し、確認画面を新規に追加します。


作成画面

通常のcommitボタンからconfirmボタンに変更しています。


_form.html.erb

  <div class="actions">

<%= form.submit 'Confirm', name: 'confirm' %>
</div>


確認画面

まずフォームを呼び出すためのビューを作成します。


new_confirm.html.erb

<h1>New Book Confirmation</h1>

<%= render 'confirm', book: @book %>



edit_confirm.html.erb

<h1>Editting Book Confirmation</h1>

<%= render 'confirm', book: @book %>


実際のconfirmのビューはこちらです。form.hidden_fieldで値を持たせて、commitボタン押下時に値を受け取れるようにしています。

さらに、前画面に戻れるようにbackボタンを追加しています。


_confirm.html.erb

<%= form_with(model: book, local: true) do |form| %>

<div class="field">
<%= form.label :title %>
<%= book.title %>
<%= form.hidden_field :title %>
</div>

<div class="field">
<%= form.label :author %>
<%= book.author %>
<%= form.hidden_field :author %>
</div>

<div class="actions">
<%= form.submit 'Back', name: 'back' %>
<%= form.submit %>
</div>
<% end %>



結果

作成画面と確認画面はこのようになります。


作成画面

スクリーンショット 2019-04-20 12.27.46.png


確認画面

スクリーンショット 2019-04-20 12.27.57.png


所感

Rails難しいですね。改善点ありましたら、アドバイスいただけると幸いです。


ソースコード

ソースはこちらにアップロードしました。

https://github.com/myzkyuki/scaffold_confirm_example