前回からの続きになりますまだ見てない方は前回の記事からご確認ください。
前回の記事でユーザー登録の仕方を記載しました。今回は住所の登録からになります。
まず、ユーザー登録の画面でユーザー情報を入力させ、それを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
コマンドが実行できましたら次にモデルにアソシエーション を記載していきます。
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モデルにもアソシエーションを記載しましょう
has_one :address
記載ができましたら次にdeviseのコントローラを作成し、編集できる形にします。
rails g devise:controllers users
これでdevise管理下のusersコントローラを作成することができました
次にルーティングを設定下行きます
Rails.application.routes.draw do
root to: 'products#index'
devise_for :users, controllers: {
registrations: 'users/registrations',
}
ルーティングが設定できましたら次にコントローラの設定をしていきます
コントローラーに必要なアクションを記載していきます。
def new
@user = User.new
end
記載ができましたら、アクションに対するビューを作成してください
= 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に保持させること
次の住所情報登録で使用するインスタンスを生成、当該ページへ遷移すること
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アクションに対応するビューを編集をしていきます。
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を作成しましょう。
= 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アクションで、ユーザー情報と住所情報全てをテーブルに保存するようにしましょう。
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に対応するビューを作成しトップページに戻れるようにしましょう。
以上で完成になります
#最後に
最後に一言、何かをインプットした際は、どのような方法でも構わないのでアウトプットすることで知識の定着になりますので皆様もやってみてはいかがでしょうか。