LoginSignup
1
0

More than 3 years have passed since last update.

ウィザード形式でユーザー登録しよう(続き)

Posted at

前回からの続きになりますまだ見てない方は前回の記事からご確認ください。

前回の記事でユーザー登録の仕方を記載しました。今回は住所の登録からになります。
まず、ユーザー登録の画面でユーザー情報を入力させ、それをsessionに保持させておきます。そして次の住所情報を登録する画面で住所情報を入力させ、最後のステップでsessionに保持していたユーザー情報と、それに関連する住所情報をテーブルに保存します。

初めに住所を登録するテーブルを作成します

ターミナル
rails g model address

コマンドを入力しましたらマイグレーションファイルが作成されますので必要なカラムを記載してください

Column Type Options
postal_code integer null:false
administrative_divisions string null:false
city string null:false
street_number string null:false
apartment string null:true
tel integer null:true,unique:ture
user_id integer null:false,foreign_key: true

Userモデルとのリレーションのために、外部キーとしてuser_idが入るようにします。
マイグレーションファイルを修正ができましたらマイグレートを実行しましょう。

ターミナル
rails db:migrate

コマンドが実行できましたら次にモデルにアソシエーション を記載していきます。

address.rb
class Address < ApplicationRecord
  validates :postal_code, presence: true, length: { maximum: 8, too_long: 'は8文字以内で記入してください'}
  validates :administrative_divisions, presence: true
  validates :street_number, presence: true
  validates :tel,length: { maximum: 13, too_long: 'は8文字以内で記入してください'}

  belongs_to :user,  optional: true
end

続いてUserモデルにもアソシエーションを記載しましょう

user.rb
has_one :address

記載ができましたら次にdeviseのコントローラを作成し、編集できる形にします。

ターミナル
rails g devise:controllers users

これでdevise管理下のusersコントローラを作成することができました

次にルーティングを設定下行きます

routes.rb
 Rails.application.routes.draw do
  root to: 'products#index'
  devise_for :users, controllers: {
    registrations: 'users/registrations',
  }

ルーティングが設定できましたら次にコントローラの設定をしていきます
コントローラーに必要なアクションを記載していきます。

userscontrollr
  def new
    @user = User.new
  end

記載ができましたら、アクションに対するビューを作成してください

mew.html.haml
= form_for(@user, url: user_registration_path,html: { class: "form_group"}) do |f|
        = render "devise/shared/error_messages", resource: @user
        .form_box
          .field
            %label{for: "nickname"} ニックネーム
            %span.form-require 必須
            %br/
            = f.text_field :nickname, autofocus: true,value:"",autocomplete: "nickname",placeholder:")フリマ"
          .field
            %label{for: "email"} メールアドレス
            %span.form-require 必須
            %br/
            = f.email_field :email, autofocus: true, autocomplete: "email",placeholder:"PC・携帯どちらでも可",value:""
          .field
            %label{for: "password"} パスワード
            %span.form-require 必須
            - if @minimum_password_length
              %em
            %br/
            = f.password_field :password, autocomplete: "new-password",placeholder:"",placeholder:"7文字以上の半角英数字"

          .field
            %label{for: ":password_confirmation"} パスワード確認
            %span.form-require 必須
            %br/
            = f.password_field :password_confirmation, autocomplete: "new-password",placeholder:"7文字以上の半角英数字"
          .field
            %h3.text-left 本人確認
            %p.l-single-text
              安心・安全にご利用いただくために、お客さまの本人情報の登録にご協力ください。他のお客さまに公開されることはありません。        

          .field_box
            %div
              %label{for: "family_name"}お名前
              %span.form-require 必須
            %div
            = f.text_field :family_name, autofocus: true, placeholder:"例) 西田",value:""
            = f.text_field :first_name,  autofocus: true, placeholder: "例) 太郎",type: "text", value: ""
          .field
            %div
              %label{for: "hurigana_family_name"} お名前ふりがな
              %span.form-require 必須
            = f.text_field :hurigana_family_name,  autofocus: true, placeholder: "例) ふりま",type: "text", value: "" 
            = f.text_field :hurigana_first_name,  autofocus: true, placeholder: "例) たろう",type: "text", value: ""
          .field
            %div
              %label{for: "birthday"} 生年月日
              %span.form-require 必須
            = f.number_field :birth_year,  autofocus: true, type: "integer", value: "" 
            %label 年
            = f.number_field :birth_month,  autofocus: true, type: "integer", value: ""
            %label 月
            = f.number_field :birth_date,  autofocus: true, type: "integer", value: "" 
            %label 日
          %p.form-info-text
            ※ 本人情報は正しく入力してください。会員登録後、修正するにはお時間を頂く場合があります。
          .actions
            = f.submit "次へ進む", class: 'btn_btn'

次の住所情報を登録するページに遷移します。しかし、その前にcreateアクション内でやらなければならないことがあります。

1ページ目で入力した情報のバリデーションチェック
1ページで入力した情報をsessionに保持させること
次の住所情報登録で使用するインスタンスを生成、当該ページへ遷移すること

usersコントローラー
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]
    @address = @user.build_address
    render :new_address
  end

次にaddressのnewアクションに対応するビューを編集をしていきます。

routes.rb
 root to: 'products#index'
  devise_for :users, controllers: {
    registrations: 'users/registrations',
  }
  devise_scope :user do
    get 'addresses', to: 'users/registrations#new_address'
    post 'addresses', to: 'users/registrations#create_address'
  end

続いて、ビューファイルであるnew_address.html.hamlを作成しましょう。

new_addres.html.haml
 = form_for(@address, html: { class: "address_group"}) do |f|
        = render "devise/shared/error_messages", resource: @address
        .form_box
          .field_address
            %label{for: "postal_code"} 郵便番号(ハイフンなし)
            %span.form-require 必須
            %br/
            = f.number_field :postal_code,autofocus: true, placeholder: "郵便番号", value: ""
          .field_address
            %label{for: "administrative_divisions"} 都道府県
            %span.form-require 必須
            %br/
            = f.text_field :administrative_divisions,autofocus: true,value:"",autocomplete: "administrative_divisions",placeholder:"都道府県"
          .field_address
            %label{for: "city"} 市区町村
            %span.form-require 必須
            %br/
            = f.text_field :city,autofocus: true, placeholder: "市区町村",type: "text", value: ""
          .field_address
            %label{for: "street_number"} 番地
            %span.form-require 必須
            %br/
            = f.text_field :street_number,autofocus: true, placeholder: "番地",type: "text", value: ""
          .field_address
            %label{for: "apartment"} マンションまたはビル
            %span.form-require 任意
            %br/
            = f.text_field :apartment,autofocus: true, placeholder: "マンションまたはビル",type: "text"
          .field_address
            %label{for: "tel"} 電話番号(ハイフンなし)
            %span.form-require 任意
            %br/
            = f.number_field :tel,autofocus: true
          .actions
            = f.submit "登録完了", class: 'btn_btn'

対応するビューファイルができましたらcreate_addressアクションと対応するビューを作成しましょう
登録の完了画面に当たる部分になりますのでこちらのビューファイルを各々が作成してください。
最後に実際に保存するフェーズを実装していきます。create_addressアクションで、ユーザー情報と住所情報全てをテーブルに保存するようにしましょう。

usersコントローラー
class Users::RegistrationsController < Devise::RegistrationsController


  def create_address
    @user = User.new(session["devise.regist_data"]["user"])
    @address = Address.new(address_params)
    unless @address.valid?
      flash.now[:alert] = @address.errors.full_messages
      render :new_address and return
    end
    @user.build_address(@address.attributes)
    @user.save
    sign_in(:user, @user)
  end

  protected

  def address_params
    params.require(:address).permit(:postal_code,:administrative_divisions,:city,:street_number,:apartment,:tel)
  end

end

最後にさて、address_createに対応するビューを作成しトップページに戻れるようにしましょう。

以上で完成になります

最後に

最後に一言、何かをインプットした際は、どのような方法でも構わないのでアウトプットすることで知識の定着になりますので皆様もやってみてはいかがでしょうか。

1
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
1
0