やりたいこと
Railsでは基本的にフォームで入力した内容はダイレクトにDBへ登録されてしまう。
Railsのformから送った内容を確認するページで見た後、再編集または登録を行いたい。
ここで実装すること
- newページからconfirmページへ遷移可能に
- newページからconfirmへ行く時にバリデーションチェック
- confirmページでnewページの内容を確認可能に
- confirmページからnewページに戻るボタンを設置
- confirmページから登録
実装方法
scaffoldのTask管理アプリに実際に実装していきます。
前準備
実装する土台を用意します。
$ rails new test_app
$ cd test_app
$ bundle install
$ rails g scaffold task title:string content:text
1. 確認ページのRoutingの追加
confirmというページで確認を行えるように穴を開けます。
Rails.application.routes.draw do
resources :tasks do
collection do
post 'confirm'
end
end
# 中略
end
下記のように出ていたらOK!
$ rake routes
Prefix Verb URI Pattern Controller#Action
confirm_tasks POST /tasks/confirm(.:format) tasks#confirm # <=追加URL
tasks GET /tasks(.:format) tasks#index
POST /tasks(.:format) tasks#create
new_task GET /tasks/new(.:format) tasks#new
edit_task GET /tasks/:id/edit(.:format) tasks#edit
task GET /tasks/:id(.:format) tasks#show
PATCH /tasks/:id(.:format) tasks#update
PUT /tasks/:id(.:format) tasks#update
DELETE /tasks/:id(.:format) tasks#destroy
2. FormからのPOSTで確認ページへ遷移させる実装
2.1. 確認アクションへのPOST
scaffoldで自動生成されたform用のパーシャルはデフォルトで登録アクションへ飛びます。
これを確認用のアクションへ飛ばすように下記のように変更します。
form_forのurlにactionを指定すればOKです。
<%= form_for @task, url: {action: 'confirm'} do |f| # <= 変更 %>
<% if @task.errors.any? %>
# 中略
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit 'next!' %>
</div>
<% end %>
2.2. 確認アクションの内容
取りあえずControllerにも対応アクションのconfirmを入れます。
Viewで該当データを表示等する為にインスタンス変数で取得します。
valid?
およびinvalid?
メソッドはバリデーションチェックなどを行うメソッドで、
バリデーションチェックがエラーになったら(エラーMSGがあったら)Form入力画面へ差し戻します。
class TasksController < ApplicationController
# 中略
def confirm
@task = Task.new(task_params) # <=POSTされたパラメータを取得
render :new if @task.invalid? # <=バリデーションチェックNGなら戻す
end
#中略
end
3. 戻るボタンと登録アクションの実装
3.1. 確認ページの実装
確認ページを作成します。
登録や戻る際にPOSTでデータを送る為にhidden_field
で情報を保持しています。
また、戻る処理を実現する為に、name属性を使用してcreatアクション内で分岐を行います。
<%= form_for @task do |f| %>
<div class="field">
title: <%= @task.title %>
<%= f.hidden_field :title # <=データ保持 %>
</div>
<div class="field">
content: <%= @task.content %>
<%= f.hidden_field :content # <=データ保持 %>
</div>
<div class="actions">
<%= f.submit 'Back!', name: 'back' # <=戻る為のname %>
</div>
<div class="actions">
<%= f.submit 'create!' %>
</div>
<% end %>
3.2. 登録アクションの実装
f.submit
のname属性の指定有無でnew画面に戻す、または登録の実行を行います。
※フォーマット指定による処理は入れていません。
def create
@task = Task.new(task_params)
if params[:back]
render :new
elsif @task.save
redirect_to @task, notice: 'Task was successfully created.'
else
render :new
end
end
# 中略
end