【この記事の説明】
現在、私はプログラミングスクールでプログラミング(主にRuby)の勉強をしています。
そして、その一環でチーム開発(メルカリもどきのサイト作成)を行っており、私はその中で記事のタイトルにあるように、ウィザード形式でユーザの登録ができるようにする作業を担当致しました。
又、スクールからの指示で、この登録フォームにはdeviseを使用するようにとのことでした。
この記事は、その担当作業についてまとめたものになります。
(記事はいくつかに分けて投稿したいと思います)
下記より、まとめを掲載致しますので、ご覧頂ければ幸いです。
【ウィザードとは】
コンピュータからの質問に答えることで物事が進んでいく方式のこと
ウィザード形式フォームとは
登録内容ごとにページを分けるフォームのこと
【今回作成したユーザ登録フォームとは】
今回作成した登録フォームはウィザード形式で3ページ分の入力をユーザにしてもらうフォームで、ページ毎にデータ保存される(データベースの)テーブルも異なるものとなっています
<1ページ目>
ユーザ情報
ニックネーム
メールアドレス
パスワード
確認用パスワード
ユーザの本名
ユーザの本名(カナ)
生年月日
<2ページ目>
ユーザー本人の住所
郵便番号
都道府県
市区町村
番地
マンションなどの部屋番号
<3ページ目>
お届け先住所
届け先の名前
郵便番号
都道府県
市区町村
番地
マンションなどの部屋番号
電話番号
【作業】
ここから私が行った作業を記事として記載していこうと思います
※この記事では、必要なテーブルの作成とルーティングを記載したいと思います
登録フォーム(haml,scss)を作成←別のチームメンバーが担当
登録フォームの基本形はチームメンバーの方が作成してくれました。
私はその作成されたフォームを使用してデータ保存ができるようにした形になります。
データベースのテーブル作成
私たちが作成したウィザード形式の登録フォームはページ毎に異なるテーブルにデータが保存されるようになっています
今回作成したウィザード形式は3ページ。つまり、テーブルは3つということになります。
今回作成したテーブルは
1ページ目の情報を保存する→Userテーブル
2ページ目の情報を保存する→Profileaddressテーブル
3ページ目の情報を保存する→Deliveryaddressテーブル
⦅テーブルの作成方法⦆
※今回はあくまで私の作業担当のところしか記事にしません。ですので、rails newなどに関しては記載致しません。
<deviseの導入>
- Gemfileにgem 'devise'を記載する
その際、記載するのはGemfile内の一番下をお勧めします
間違ってgroup:test do~end内とかに記載するとtest環境でしか使用できないとかがある為です - コンソールで下記のコマンドを実行する
% bundle install
% rails g devise:install
% rails g devise user
※ここで重要なことはUserテーブルはdeviseで作成したということです
<他2つのテーブル作成>
% rails g model Profieladdress
% rails g model Deliveryaddress
このテーブルはdeviseでは作成せず、rails g model で作成します
カラムの作成方法
テーブルは作成できましたが今のままでは、何のデータも入らないテーブルが3つできただけです
ということで、テーブルにカラムを作成します
% rails g devise user
% rails g model Profieladdress
% rails g model Deliveryaddress
上記のコマンド実行時に、マイグレーションファイルが一緒に作成されているので、そこに必要なカラムを追加していきます
class DeviseCreateUsers < ActiveRecord::Migration[5.2]
def change
create_table :users do |t|
## Database authenticatable
# 元々あるカラム↓
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
# 追加したカラム↓
t.string :nickname, null: false
t.string :family_name, null: false
t.string :given_name, null: false
t.string :family_name_kana, null: false
t.string :given_name_kana, null: false
t.date :birthday, null: false
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
end
end
下記の2つのマイグレーションには
```の記述があります
これは、Userテーブルに紐づくテーブルであることを意味します
ウィザード形式でユーザ登録をする上では重要な部分だと私は思っています
```ruby:Profileaddressテーブル
class CreateProfileaddresses < ActiveRecord::Migration[5.2]
def change
create_table :profileaddresses do |t|
t.string :postal_code
t.string :prefectures
t.string :city
t.string :address
t.string :building
t.references :user, foreign_key: true
t.timestamps
end
end
end
class CreateDeliveryaddresses < ActiveRecord::Migration[5.2]
def change
create_table :deliveryaddresses do |t|
t.string :family_name, null: false
t.string :given_name, null: false
t.string :family_name_kana, null: false
t.string :given_name_kana, null: false
t.string :postal_code, null: false
t.string :prefectures, null: false
t.string :city, null: false
t.string :address, null: false
t.string :building
t.string :phone_number
t.references :user, foreign_key: true
t.timestamps
end
end
end
※:postal_code、:phone_numberは最初、integer型の予定でしたが、:phone_numberは0を認識させたい為に、:postal_codeは正規表現でバリデーションをかける為にstring型に変更しました
% rails db:migrate
マイグレーションファイルの内容(テーブルのカラム)を設定したら、ファイルを反映させる
モデルでバリデーション&アソシエーションの設定
記述が長くなるので、別の記事に記載と思います
そちらをお読みください
アソシエーションについて→ウィザード形式でユーザ登録のフォームを作成してみた②-2 〜viewとcontroller〜
バリデーションについて→ウィザード形式でユーザ登録のフォームを作成してみた③-1 〜バリデーション〜
deviseでコントローラの作成
deviseのusersコントローラを作成します
% rails g devise:controllers users
これで、コントローラは作成できました。
ですが、このままだと以下のようにdevise管理下のコントローラが呼ばれてしまいます
Prefix Verb URI Pattern Controller#Action
root GET / products#index
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
logout_mypages GET /mypages/logout(.:format) mypages#logout
card_mypages GET /mypages/card(.:format) mypages#card
newcard_mypages GET /mypages/newcard(.:format) mypages#newcard
mypages GET /mypages(.:format) mypages#index
products GET /products(.:format) products#index
new_product GET /products/new(.:format) products#new
edit_product GET /products/:id/edit(.:format) products#edit
product GET /products/:id(.:format) products#show
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
ここで、以下のようにdevise部分のルーティングを設定します
Rails.application.routes.draw do
root to: 'products#index'
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations',
}
devise_scope :user do
post '/profileaddresses', to: 'users/registrations#new_profileaddresses'
post '/deliveryaddresses',to: 'users/registrations#new_deliveryaddresses'
end
resources :mypages, only: [:index] do
collection do
get 'logout'
get 'card'
get 'newcard'
end
end
resources :products, only: [:index, :new, :edit, :show]
end
このように設定後、rails routesで確認するとdevise/registrations#xxxとなっていたところが、users/registrations#xxxとなっていることがわかります
つまり、ここでお伝えしたいのは、
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations',
}
を記述することで、users/registrations#xxx,users/sessions#xxxとなることです
Prefix Verb URI Pattern Controller#Action
root GET / products#index
new_user_session GET /users/sign_in(.:format) users/sessions#new
user_session POST /users/sign_in(.:format) users/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) users/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel
new_user_registration GET /users/sign_up(.:format) users/registrations#new
edit_user_registration GET /users/edit(.:format) users/registrations#edit
user_registration PATCH /users(.:format) users/registrations#update
PUT /users(.:format) users/registrations#update
DELETE /users(.:format) users/registrations#destroy
POST /users(.:format) users/registrations#create
profileaddresses POST /profileaddresses(.:format) users/registrations#new_profileaddresses
deliveryaddresses POST /deliveryaddresses(.:format) users/registrations#new_deliveryaddresses
logout_mypages GET /mypages/logout(.:format) mypages#logout
card_mypages GET /mypages/card(.:format) mypages#card
newcard_mypages GET /mypages/newcard(.:format) mypages#newcard
mypages GET /mypages(.:format) mypages#index
products GET /products(.:format) products#index
new_product GET /products/new(.:format) products#new
edit_product GET /products/:id/edit(.:format) products#edit
product GET /products/:id(.:format) products#show
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
ルーティングのカスタマイズ
次に、devise_scope :user doの部分についてです
ウィザード形式で3ページの入力ページを作成しているので、newアクションだけでは足りません。
その為、new_profileaddressesアクションとnew_deliveryaddressesアクションを作成し、そのルーティングをdevise_scope :user doによって行っています
devise_scope :user do
post '/profileaddresses', to: 'users/registrations#new_profileaddresses'
post '/deliveryaddresses',to: 'users/registrations#new_deliveryaddresses'
end
又、なぜPOSTのみルーティングしているのかですが、GETのルーティングが必要ないからです
↓
viewからnew_profileaddressesアクション,new_deliveryaddressesアクションにデータを送ることがある→POSTは必要
railsは、アクション後にそのアクション内でどこかに飛ぶ記述がなければ、そのアクション名と同じ名前のviewに飛ぶようになっている→GETは不必要
詳しくは、次の記事でcontrollerのコードを記載しているので確認してください
【次の記事】
この記事では、テーブル作成とルーティング(devese/→users/)について記述しました。
次の記事ではviewとcontrollerについて記載をしたいと思います
次の記事 → ウィザード形式でユーザ登録のフォームを作成してみた②-1 〜viewとcontroller〜
【参考資料】
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
ウィザードフォーム形式フォームの実装 -devise×session×データを複数テーブルに分けて保存 ver.- (rails)