さらなる高みへ -higher ground -

プログラミング学習の定着を狙いとしたアウトプット(独り言)をしてみるブログ

ログイン機能を追加する2

ここでは前回のログイン機能を改善する。

ログイン・サインアップ画面のビューを変更する

deviseを使用してログイン機能を実装すると自動的にログイン画面とサインアップ画面が生成される。
元のままの見た目だと味気ないため、以下画像のようなサインイン/サインアップ画面に変更する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//133f5392c783d33e1dc64846a1e3ed74.png

作業内容
  1. devise用のビューファイルを作成する
  2. ログイン・サインアップ画面のビューファイルを編集する

devise用のビューファイルを作成する

deviseでログイン機能を実装すると、ログイン・サインアップ画面は自動的に生成されるがビューファイルとしては生成されない。
これは、deviseのGem内に存在するビューファイルを読み込んでいるためである。

ビューファイルに変更を加えるためには、deviseのコマンドを利用してビューファイルを生成する必要がある。

下記のコマンドを実行し、devise用のビューファイルを生成する

$ rails g devise:views

新規作成されるファイル

app/views/devise以下のディレクトリにあるビューファイル各種

ログイン・サインアップ画面のビューファイルを編集する

上記の作業でdevise用のビューファイルを生成することができた。
今度は生成されたビューファイルを編集してレイアウトを変更していく。

サインアップ画面はapp/views/devise/registrations/new.html.erb、ログイン画面のビューはapp/views/devise/sessions/new.html.erbというビューファイルが対応している。

上記2つのファイルを、それぞれ以下のように変更する

元の記述を、以下のコードで全て置き換える。

app/views/devise/registrations/new.html.erb

<div class="contents row">
  <h2>Sign up</h2>

  <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
    <%= render "devise/shared/error_messages", resource: resource %>

    <div class="field">
      <%= f.label :email %><br />
      <%= f.email_field :email %>
    </div>

    <div class="field">
      <%= f.label :password %>
      <% if @validatable %>
      <em>(<%= @minimum_password_length %> characters minimum)</em>
      <% end %><br />
      <%= f.password_field :password, autocomplete: "new-password" %>
    </div>

    <div class="field">
      <%= f.label :password_confirmation %><br />
      <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
    </div>

    <div class="actions">
      <%= f.submit "Sign up" %>
    </div>
  <% end %>

  <%= render "devise/shared/links" %>
</div>

 

app/views/devise/sessions/new.html.erb

<div class="contents row">
  <h2>Log in</h2>

  <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
    <div class="field">
      <%= f.label :email %><br />
      <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
    </div>

    <div class="field">
      <%= f.label :password %><br />
      <%= f.password_field :password, autocomplete: "current-password" %>
    </div>

    <% if devise_mapping.rememberable? %>
      <div class="field">
        <%= f.label :remember_me %>
        <%= f.check_box :remember_me %>
      </div>
    <% end %>

    <div class="actions">
      <%= f.submit "Log in" %>
    </div>
  <% end %>

  <%= render "devise/shared/links" %>
</div>

ファイル内に出てくるform_forに関しては、応用カリキュラムのRails2で詳しく学習。今は、変更箇所を細かく理解しなくてOK。

変更できたか確認する

トップページを開き下記のアドレスを追記する。

トップページアドレス/users/sign_in以下の画面になっていることを確認する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//08db18d8ff35d2c0c6434153bd96d904.png

トップページを開き下記のアドレスを追記する。
トップページアドレス/users/sign_up以下の画面になっていることを確認する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//843866fd9f9ea66452f8b7b1ac7ce68d.png

サインアップ時にニックネームを登録する

現在、サインアップ時に登録する情報はメールアドレスとパスワードの2つである。
これに加えてニックネームを登録できるようにする。

作業内容

1.ユーザーテーブルにカラムを追加する

2.登録画面のビューを編集する

3.ストロングパラメーターを編集する

1.ユーザーテーブルにカラムを追加する

ニックネームを登録するために、usersテーブルにニックネームを保存するためのカラムを追加する。
追加したカラムに、サインアップ時に登録するニックネームを保存する。

カラムを追加するマイグレーションファイルの作成

カラムを追加するマイグレーションファイルを作成するためには、下記のコマンドを実行する。

$ rails g migration Addカラム名To追加先テーブル名 追加するカラム名:型

例えば、userの自己紹介を保存するためのカラム、introductionカラムをusersテーブルにtext型で追加したいとする。
その時は、以下の例のように書く。


ターミナル

$ rails g migration AddIntroductionToUsers introduction:text
# usersテーブルにintroductionカラムをtext型で追加するマイグレーションファイルの作成

この時、「Add」「Introduction」「To」「Users」と、単語の頭文字が大文字になっていることに注目。

スネークケースとキャメルケース

プログラムが単語の区切りを認識する際、2通りの方法がある。
それらをそれぞれ「スネークケース、キャメルケース」と呼ぶ。

スネークケースは、例えば「sample_hoge_huga」のように「_」で単語を区切る方法である。
対してキャメルケースは、「SampleHogeHuga」のように単語の頭文字を大文字にすることで単語を区切る。

 問題1:usersテーブルに、nicknameカラムをstring型で追加しましょう

作業ファイル:なし
ヒント1:マイグレーションファイルを作成しても、実行しなければカラムは追加されません。
ヒント2:もし誤ったマイグレーションファイルを実行してしまった場合はロールバックしましょう。

 【 問題1の解答を確認する 】 

 

Addカラム名To追加先テーブルカラム名の部分は、必ずしも厳密なカラム名を入力する必要はありません。
今回はnicknameというカラムを追加するので今回はNicknameと記述しましょう。

 

実際にカラムが追加されたか確認する

phpMyAdminを開き、usersテーブルを開く。
メニューの構造をクリックし、一番下に新しく追加されたnicknameカラムを確認する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//072b3f0fccc93cd4e0240128bd6327e4.jpeg

2.登録画面のビューを編集する

これでDB側の準備は整ったため、続いてユーザーの新規登録画面にニックネームを登録するためのフォームを追加する。
ユーザーの新規登録画面のビューは、app/views/devise/registrations/new.html.erbである。
その際、オプションをつけることで入力できる文字数を6文字以下にする。

text_field:maxlengthオプション

maxlengthは、text_fieldというinputタグを生成するヘルパーメソッドにつけることができるオプションである。

app/views/devise/registrations/new.html.erb

  <div class="field">
    <%= f.text_field :nickname, autofocus: true, maxlength: "6" %>
  </div>

この場合、生成されたフォームに7文字以上入力すると、エンターキーを押した瞬間に6文字までカットされる。

app/views/devise/registrations/new.html.erbを以下のように編集する

app/views/devise/registrations/new.html.erb

<div class="contents row">
  <h2>Sign up</h2>

  <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
    <%= render "devise/shared/error_messages", resource: resource %>

    <div class="field">
      <%= f.label :nickname %> <em>(6 characters maximum)</em><br />
      <%= f.text_field :nickname, autofocus: true, maxlength: "6" %>
    </div>

    <div class="field">
      <%= f.label :email %><br />
      <%= f.email_field :email %>
    </div>

    <div class="field">
      <%= f.label :password %>
      <% if @validatable %>
      <em>(<%= @minimum_password_length %> characters minimum)</em>
      <% end %><br />
      <%= f.password_field :password, autocomplete: "new-password" %>
    </div>

    <div class="field">
      <%= f.label :password_confirmation %><br />
      <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
    </div>

    <div class="actions">
      <%= f.submit "Sign up" %>
    </div>
  <% end %>

  <%= render "devise/shared/links" %>
</div>

3.ストロングパラメーターを編集する

サインアップ時に入力する情報はパラメーターとしてサーバーに送信される。
通常のリクエストの場合は、コントローラに記述してあるストロングパラメーターで受け取れるパラメーターを制限する。
しかし、deviseでログイン機能を実装した場合のパラメーターの受け取り方は通常とは異なる。
ログイン時に送られてくるパラメーターを制限するストロングパラメーターは、deviseのGem内に記述されているため編集することはできない。

https://tech-master.s3.amazonaws.com/uploads/curriculums//da0f7d41792819f24a70ff434e2f56e3.png

ではどうするかというと、今回追加したニックネームを受け取れるようにするにはdeviseが提供しているconfigure_permitted_parametersメソッドを利用する。

configure_permitted_parametersメソッド

deviseでは初期状態でサインアップ時にメールアドレスとパスワードのみを受け取るようにストロングパラメーターが設定してあるため、追加したキーのパラメーターは許可されていない。
追加のパラメーターを許可したい場合は、application_controllerにおいてbefore_actionにconfigure_permitted_parametersメソッドを設定する。

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:ストロングパラメーターを追加したいアクション名, keys: [:追加するキー])
  end
end

今回は、sign_upアクションに対してnicknameというキーのパラメーターを追加で許可する。

app/controllers/application_controllerを以下のように編集する

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end
end

登録画面のビューを確認

トップページを開き下記のアドレスを追記する。
トップページアドレス/users/sign_upnicknameを入力するフォームができていることを確認する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//72f8e6cc1fae83ba3dbe228dfda0b66c.png

ここまでできたら、実際にユーザーを作成してニックネームが登録できるか確かめてみる。

pictweetのトップページから、新規でユーザーを作成する

先ほどのページから新規で登録をし、nicknameを保存する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//9c4df47108ffe1fdefd21339ef84593b.jpeg

きちんと保存できているかどうかphpMyAdminで確認する。
usersテーブルを開きメニューの「表示」を選択すると確認できる。nicknameカラムは一番右にある。

f:id:the_road_to_engineer:20200112185435p:plain

このままだと確認するたびに一番右まで表示させなくてはいけないため不便である。
メニューの「構造」の中の中央付近にある「カラムを移動させる」で「e-mail」の右側に表示させるよう変更もできる。

下の動画を参考に移動させてみる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//b6ba20eff1d4f84dcc02ea590ba2d39c.gif

「表示」を選択し、確認する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//15c5e6da30f83e0245194a82ae319df4.jpeg

保存できていることを確認したら次へ進む。

要点チェック