2
0

More than 3 years have passed since last update.

Rails ウィザード形式導入について 2

Last updated at Posted at 2020-04-01

はじめに

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する。

難しい!でも自作アプリには入れたいです!もうひと頑張り!

続きは次回!

さいごに

日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0