はじめに
Rails ウィザード形式導入について 1 はこちらをクリック願います。
チーム開発でフリマサイトを開発致しました。
その際、ユーザーの新規登録画面でウィザード形式を導入致しましたので、内容を整理します。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。
前提
- ユーザー情報(User)については 以下 A と記述します。
- 住所情報(Destination)については 以下 B と記述します。
Aの新規登録のnewアクションとビュー
- app/controllers/users/registrations_controller.rbを見てみてください。
- えらいことになっているかと思います・・・
- なんだこれ・・・
app/controllers/users/registrations_controller.rb
# frozen_string_literal: true
class Users::RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
# GET /resource/sign_up
# def new
# super
# end
# POST /resource
# def create
# super
# end
# GET /resource/edit
# def edit
# super
# end
# PUT /resource
# def update
# super
# end
# DELETE /resource
# def destroy
# super
# end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
# def cancel
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
# def configure_sign_up_params
# devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
# end
# If you have extra params to permit, append them to the sanitizer.
# def configure_account_update_params
# devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
# end
# The path used after sign up.
# def after_sign_up_path_for(resource)
# super(resource)
# end
# The path used after sign up for inactive accounts.
# def after_inactive_sign_up_path_for(resource)
# super(resource)
# end
end
- コメントアウトしている箇所はすでにDevise::RegistrationsControllerで定義されているものです。
- コメントアウト部分を外して上書きすることができます。(メソッドのオーバーライド)
- superはスーパークラス(今回であればDevise)のメソッドを呼び出しています。
とりあえずコメントアウト部分(superクラスの呼び出し部分)を全部消してしまいます・・・
- deviseとUserモデルが紐づくように設定してあるので、superで呼び出してもdeviseは同様の操作を行ってくれるようです。
- 勉強中ですので、super呼び出し方法についてはお待ちください(泣)
newアクションを定義する
app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def new
@user = User.new
end
end
そして、対応しているビューも編集する
- 参考程度にみてください。このまま入力するとエラーが出るかも・・・です。
app/views/devise/registrations/new.html.haml
.main
.title
.title__font
A情報入力
= form_for(@user, url: user_registration_path) do |f|
.name-information
.name-information__item
.name-information__item__nicname
= f.label :name,"ニックネーム"
.name-information__name
= f.text_field :name,size:26
.email
.email__information
.email__information__address
= f.label :email,"メールアドレス"
.email__information
= f.email_field :email, autofocus: true, autocomplete: "email",size:26
.password
.password__item
.password__item__pass
= f.label :password,"パスワード"
.password__item__note
- if @minimum_password_length
(#{@minimum_password_length} 文字以上必要です)
.password__input
.password__description
= f.password_field :password, autocomplete: "new-password", size:26
.re-enter
.re-enter__item
.re-enter__item__pass
= f.label :password_confirmation,"確認用パスワード "
.re-enter__itempass
= f.password_field :password_confirmation, autocomplete: "new-password",size:26
.terms-of-service
.terms-of-service__btm
%input#submit_button1{:name => "submit", :type => "submit", :value => "次へ進む"}/
Aの新規登録のcreateアクションとビュー
- 1ページ目で入力した情報のバリデーションチェックをします。
- 1ページで入力した情報をsessionに保持させます。
- 次のBの登録で使用するインスタンスを生成、当該ページへ遷移するようにします。
createアクションを定義する(追記してください)
app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
# 省略
def create
@user = User.new(sign_up_params)
unless @user.valid?
flash.now[:alert] = @user.errors.full_messages
render :new and return
end
session["devise.regist_data"] = {user: @user.attributes}
session["devise.regist_data"][:user]["password"] = params[:user][:password]
@destination = @user.build_destination
render :new_destination
end
protected
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
end
end
1ページ目で入力した情報のバリデーションチェック
- Userモデルのインスタンスを生成する。
- 1ページ目から送られてきたパラメータをインスタンス変数@userに代入する。
- そのインスタンス変数に対してvalid?メソッドを適用する。
- 送られてきたパラメータが指定されたバリデーションに違反しないかどうかチェックすることができる。
- falseになった場合は、エラーメッセージとともにnewアクションへrenderする。
1ページで入力した情報をsessionに保持させる
- A情報だけではなく、B情報までページ遷移した後に保存するという機能を達成するのが目的です。
- そのために、sessionという機能を用いる。
- sessionとは、ページが遷移しても情報が消えることが無いように、クライアント側で保持をさせておく機能のことをいうようです。
- A情報のバリデーションチェック後、session["devise.regist_data"]に値を代入する。
- この時、sessionにハッシュオブジェクトの形で情報を保持させるために、attributesメソッドを用いてデータを生成する。
- また、paramsの中にはパスワードの情報は含まれているが、attributesメソッドでデータ整形をした際にパスワードの情報は含まれない。
- そこで、パスワードを再度sessionに代入する。
B情報登録で使用するインスタンスを生成、B情報登録ページへ遷移する
- 次ページで、ユーザーモデルに紐づくB情報を入力させるため、該当するインスタンスを生成しておく必要がある。
- そのために、build_destinationで今回生成したインスタンス@userに紐づくDestinationモデルのインスタンスを生成する。
- ここで生成したDestinationモデルのインスタンスは、@destinationというインスタンス変数に代入する。
- そして、B情報を登録させるページを表示するnew_destinationアクションのビューへrenderする。
難しい!でも自作アプリには入れたいです!もうひと頑張り!
続きは次回!
さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。