ユーザー情報の編集
ここまでの作業で、Facebookだけでなく、Twitterでも連携してユーザー登録を行うことができるようになりました。ここからは、登録したユーザー情報を編集可能にしていきます。
氏名の表示
ユーザー情報を編集可能にする前に、ログイン後のトップページにメールアドレスだけでなく、氏名も表示するようにします。
…(中略)… <div>name: <%= current_user.name %></div> <div>email: <%= current_user.email %></div>
これでログインした状態でアクセスするとSNSから取得した氏名が表示されます。
なお、氏名に入ってくるデータはSNS上で登録されているものに依存します。Userモデルの実装の通り、auth.info.nameでSNSから取得される情報となります。
…(中略)… def find_or_create_for_oauth(auth) find_or_create_by!(email: auth.info.email) do |user| user.provider = auth.provider user.uid = auth.uid #user.name = auth.info.name# …(中略)…
なお、Facebookの場合、漢字で登録している場合、姓と名が逆さまになって取得されてしまいます。より実践的にするためには、last_name(姓)とfirst_name(名)を取得するなどの工夫が必要である点に注意してください。
ヘッダーにリンクを追加
以下のコマンドでルーティングを確認するとユーザー情報編集画面へのPrefixはedit_user_registrationであることが確認できます。
bin/rails routes
▼
…(中略)… edit_user_registration GET /users/edit(.:format) users/registrations#edit …(中略)…
ログイン時に表示されるヘッダーに、ユーザー情報編集画面へのリンクを追加します。
…(中略)… <% if user_signed_in? %> <%= link_to 'logout', destroy_user_session_path, method: :delete %> <%= link_to 'edit', edit_user_registration_path %> # 追加 <% else %> …(中略)…
ヘッダー修正後の表示は以下の通りです。
氏名を登録/編集可能にする
はじめに、氏名(users.name)を登録/編集可能にするためにユーザー情報の登録画面と編集画面のビューをそれぞれ修正します。
<h2>Sign up</h2> <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= devise_error_messages! %> <div class="field"> <%= f.label :name %><br /> <%= f.text_field :name, autofocus: true, autocomplete: "off" %> </div> …(中略)…
登録画面の表示は以下の通りです。
続いて編集画面のビューの修正を行います。
<h2>Edit <%= resource_name.to_s.humanize %></h2> <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> <%= devise_error_messages! %> <div class="field"> <%= f.label :name %><br /> <%= f.text_field :name, autofocus: true, autocomplete: "off" %> </div> …(中略)…
編集画面の表示は以下の通りです。
次に、氏名(name)の登録/編集を許可するStrong Parametersの設定をコントローラーに追加します。deviseでは、このための設定を行うメソッドが事前にコメントアウトされた状態で用意されています。
[Note]Strong Parameters(ストロングパラメーター)とは
フォームから送信(POST)されたデータのうち、指定したものだけに限定するための仕組みです。Rails4から組み込まれています。
対象のコントローラーを以下の通り修正します。
…(中略)… class Users::RegistrationsController < Devise::RegistrationsController before_action :configure_sign_up_params, only: [:create] # コメントアウトを外す before_action :configure_account_update_params, only: [:update] # コメントアウトを外す …(中略)… protected # コメントアウトを外す # If you have extra params to permit, append them to the sanitizer. def configure_sign_up_params # コメントアウトを外す devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) end # コメントアウトを外す # If you have extra params to permit, append them to the sanitizer. def configure_account_update_params # コメントアウトを外す devise_parameter_sanitizer.permit(:account_update, keys: [:name]) end # コメントアウトを外す …(中略)…
configure_sign_up_paramsメソッドのdevise_parameter_sanitizerには認証に使うモデル(ここではUserモデル)のフォームオブジェクトが代入されています。permitの第1引数に登録フローであることを示す:sign_upが指定されています。第2引数の:keysをキーとするハッシュの値には、デフォルトでは[:attribute]が指定されています。この:attributeを更新したい認証用モデルの属性を配列で指定するように変更してください。この場合はnameが対象となるので:nameに書き換えています。
ユーザー情報編集の動作確認
さて、これでユーザー登録/編集時に氏名(name)を登録または更新することができるようになりました。前述の方法同様、pumaサーバーを起動します。
bin/bundle exec puma -C config/puma.rb
「https://127.0.0.1:9292」にアクセスしてログイン状態が保たれていなければログイン画面にリダイレクトするので、再度[Sign in with Twitter]リンクをクリックしてください。ログインするとヘッダーに[edit]リンクが表示され、名前(name)とメールアドレス(email)が表示されることが確認できます。
[edit]リンクをクリックして氏名を変更してみます。deviseのデフォルトではユーザー情報を何かしら変更する場合パスワードの入力が必要です。SNS認証した後にUserモデルのfind_or_create_for_oauthメソッドで、パスワードを生成してログに出力しています。
def find_or_create_for_oauth(auth) find_or_create_by!(email: auth.info.email) do |user| user.provider = auth.provider user.uid = auth.uid user.name = auth.info.name user.email = auth.info.email password = Devise.friendly_token[0, 20] logger.debug password # ログ出力箇所 user.password = password end end
編集画面で氏名(Name)をデフォルトの値からここでは「tchikuba」に変更し、log/development.logファイルからパスワードの出力をコピーして[Current password]テキストボックスにパスワードを入力して、[Update]ボタンをクリックします。
編集に成功すると「Your account has been updated successfully.」というメッセージとともに氏名(name)が更新されていることが画面上からも確認できます。
まとめ
ここまで、deviseで作成したアプリにOmniAuthを追加してFacebook/Twitter連携機能を実装し動作確認までを行いました。基本的な使い方はここで紹介した通りでよいのですが、例えばFacebookとTwitterで動作を変更するなどカスタマイズするには自分でコードを記述する必要が出てくるので注意が必要です。
逆にdeviseやOmniAuthが提供するレールに乗れば、かなり簡単にユーザー認証機能やSNS連携機能を実装することができます。
次回は、ページネーションを実現する定番gem「Kaminari」を紹介する予定です。