Devise の User に Profile を紐付けるところができたので、Profile を参照したり編集する Controller と View を作っていきます。
Devise デフォルトのユーザIDやパスワード、email の編集画面もマージして以下のような画面で参照し、編集リンクからそれぞれを個別に編集できるようにします。また、Deivseのユーザ情報編集では 1画面でユーザ名やパスワード、email の編集が行えましたが、パスワードの変更しないときにも confirm パスワードを入れていて、パスワード変更と紛らわしいので、それぞれ画面をわけてしまう方向で実装します。
アカウントコントローラの作成
Deviseのユーザ情報と、Profile 情報の表示用のコントローラとして Account コントローラを作成します。 個々の値の編集は、それぞれに対応したコントローラを定義して対応します。いわゆる DHH 流ルーティングで実装していきます。
参照: DHHはどのようにRailsのコントローラを書くのか
Account Controller の作成
アカウントコントローラを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ bundle exec rails g controller accounts show create app/controllers/accounts_controller.rb route get 'accounts/show' invoke erb create app/views/accounts create app/views/accounts/show.html.erb invoke test_unit create test/controllers/accounts_controller_test.rb invoke helper create app/helpers/accounts_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/accounts.coffee invoke scss create app/assets/stylesheets/accounts.scss |
次に、ルーティングを編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Rails.application.routes.draw do resource :account, :only => [:show] # devise_for :users devise_for :users, controllers: { sessions: 'users/sessions', passwords: 'users/passwords', registrations: 'users/registrations' } get 'home/index' root to: "home#index" # For details on the DSL available within this file, # see http://guides.rubyonrails.org/routing.html end |
ルーティング確認
1 2 3 4 5 |
$ bundle exec rails routes Prefix Verb URI Pattern Controller#Action account GET /account(.:format) accounts#show new_user_session GET /users/sign_in(.:format) users/sessions#new <snip> |
Account コントローラを編集します。
1 2 3 4 5 6 |
class AccountsController < ApplicationController before_action :authenticate_user! def show end end |
Account/show の View を編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<div class="card col-sm-10 mx-auto mt-5 px-0"> <div class="card-header bg-white"> <h2>アカウント情報</h2> </div> <div class="card-body"> <div class="row"> <div class="col-sm-8"> <table class="table"> <tbody> <tr> <td>名前:</td> <td><%= current_user.profile.name %></td> <td>編集</td> </tr> <tr> <td>ユーザID:</td> <td><%= current_user.username %></td> <td>編集</td> </tr> <tr> <td>メールアドレス:</td> <td><%= current_user.email %></td> <td>編集</td> </tr> <tr> <td>パスワード:</td> <td>(非表示)</td> <td>編集</td> </tr> <tr> <td>自己紹介:</td> <td><%= current_user.profile.description %></td> <td>編集</td> </tr> </tbody> </table> </div> <div class="col-sm-4"> <div class="d-flex flex-column">編集</div> </div> </div> </div> </div> |
こんな画面が見えるようになります。
Profile 中の name を編集可能にする
次に、Profile 中の name を編集するコントローラと画面を作成します。
ルーティング設定
DHH 流のルーティングを行います。account/name に対して GET と PUT/PATCH で編集用画面と編集を行えるように account の下に name を定義します。edit で編集用画面の表示、update で edit 画面で submit した際の編集の実行です。
1 2 3 4 5 6 |
Rails.application.routes.draw do resource :account, :only => [:show] do resource :name, :only => [:edit, :update], module: "accounts" end <略> end |
ルーティング確認
1 2 3 4 5 6 7 |
$ bundle exec rails routes Prefix Verb URI Pattern Controller#Action edit_account_name GET /account/name/edit(.:format) accounts/names#edit account_name PATCH /account/name(.:format) accounts/names#update PUT /account/name(.:format) accounts/names#update account GET /account(.:format) accounts#show <略> |
コントローラの作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ bundle exec rails g controller accounts/names edit update create app/controllers/accounts/names_controller.rb route namespace :accounts do get 'names/edit' get 'names/update' end invoke erb create app/views/accounts/names create app/views/accounts/names/edit.html.erb create app/views/accounts/names/update.html.erb invoke test_unit create test/controllers/accounts/names_controller_test.rb invoke helper create app/helpers/accounts/names_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/accounts/names.coffee invoke scss create app/assets/stylesheets/accounts/names.scss |
ルーティングが追加されてしまいますが、すでに設定しているので、上記で追加されたルーティングは削除してください。
コントローラの編集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class Accounts::NamesController < ApplicationController before_action :authenticate_user! before_action :set_profile def edit end def update respond_to do |format| if @profile.update(profile_params) format.html { redirect_to account_path, notice: "Profile was successfully updated." } else format.html { render :edit } end end end private def set_profile @profile = current_user.profile end def profile_params params.require(:profile).permit(:name) end end |
View の編集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<div class="card col-sm-10 mt-5 mx-auto px-0"> <div class="card-header"> <H3>名前を変更する</h3> </div> <div class="card-body"> <%= form_with(model: @profile, url: account_name_path, method: :put, local: true) do |form| %> <div class="form-group"> <%= form.label :name, "名前", :class => "form-label" %> <%= form.text_field :name, :class => "form-control" %> </div> <div class="actions float-right"> <%= link_to 'キャンセル' , account_path, :class => "btn btn-light" %> <%= form.submit "名前更新", :class => "btn btn-primary" %> </div> </div> <% end %> </div> |
ここまでで、rails サーバを再起動して、account/name/edit を叩けば名前編集画面が表示され、名前が編集できると思います。
account 画面のリンク設定
上記までで名前の編集が行えることが確認できたら、account 画面の名前の「編集」リンクに、上記画面へのリンクを張っておきます。
1 2 3 4 5 |
<tr> <td>名前:</td> <td><%= current_user.profile.name %></td> <td><%= link_to "編集", edit_account_name_path %></td> </tr> |