ユーザ管理機能はとても便利なRuby on RailsのGem機能です!
備忘録として投稿します!
目的
- deviseを理解
- deviseを使用したユーザー登録の理解
ログイン機能の実装
- ユーザー登録したユーザーのみがアプリを使えるようにする
- ログインしてないユーザーは投稿機能のアプリだと
新規作成、編集、削除機能などが使えないようにする
ライブラリのインストール
#### devise
ユーザー管理機能を簡単に実装するためのGem
Gemfile
gem 'devise'
ターミナル
bundle install
Gemインストール後はサーバー再起動
インストールしたGemの反映のタイミングが、サーバー起動時であるため
ターミナル
deviseの設定ファイルを作成
rails g devise::innstall コマンド
追加したdeviseというGemの「設定関連に使用するファイル」を自動で生成するコマンド
rails g devise:install
deviseのUserモデルを作成
rails g deviseコマンド
deviseによるユーザー機能を対象を指定することで、モデルとマイグレーションの生成やルーティングの設定などをまとめて処理する
rails g devise user
config/routes.rb
に自動的にルーティング追加
db/migrate/20XXXXXXXXX_devise_create_users.rb
メールアドレス
パスワードのカラム
レコードの作成日時と更新日時を管理するためのカラム
マイグレーション実行
rails db:migrate
ローカルサーバー再起動
deviseのビュー作成ーファイル作成
自動的にログイン、サインアップ画面が作成されているがビューファイルとしては生成されていない
deviseのGem内に存在するビューファイルを読み込んでいるため
rails g devise:viewsコマンド
deviseに用意されたビューファイルをコピーし、app/views
の配下に配置してくれるコマンド
rails g devise:views
app/views/devise/sessions/new.html.erb
<div class="contents row">
<div class="container">
<h2>Log in</h2>
<%= form_with model: @user, url: user_session_path, id: 'new_user', class: 'new_user', local: true do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<% if devise_mapping.rememberable? %>
<div class="field">
<%= f.label :remember_me %><br />
<%= f.check_box :remember_me %>
</div>
<% end -%>
<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>
</div>
</div>
app/views/devise/registrations/new.html.erb
<div class="contents row">
<div class="container">
<h2>Sign up</h2>
<%= form_with model: @user, url: user_registration_path, id: 'new_user', class: 'new_user', local: true 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 @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
</div>
</div>
ログイン画面
http://localhost:3000/users/sign_in
サインアップ画面
http://localhost:3000/users/sign_up
サインアップ時の名前登録
userテーブルにカラム追加
rails g nigrationコマンド
マイグレーションを生成するコマンド
rails g migration Addカラム名To追加先テーブル名 追加するカラム名:型
テーブルにカラムを追加する際に必要なコードが記述された状態で、マイグレーションが生成
rails g migration AddNicknameToUsers nickname:string
rails fb:migrate
カラム変更したのでサーバー再起動
rails s
サインアップ画面編集
ニックネームを6文字以内に登録
maxlengthオプション
inputタグを生成するヘルパーメソッドである、text_fieldにつけることができるオプション。入力できる最大文字数を指定できる
<div class="field">
<%= f.label :nickname %> <em>(6 characters maximum)</em><br />
<% f.text_field :nickname, autofocus: true, maxlength: "6" %>
</div>
ストロングパラメータ使用する
サインアップ時に入力する情報はパラメーターとしてサーバーに送信される
ストロングパラメーターをコントローラーに記述
しかし、deviseの処理を行うコントローラーはGem内に記述されていうrため、 編集することができない
また、decviseでログイン機能を実装した場合は、paramsの他に、paramsとは異なる形のパラメーターも受け取る。
deviseのコントローラーにストロングパラメーターを反映する方法と、
devise特有のパラメーターを取得する方法が、必要
devise_parameter_sanitizerメソッド
deviseにおけるparamsのようなメソッド。
deviseのUserモデルに関わる「ログイン」「新規登録」などのリクエストからパラメーターを取得
このメソッドとpermitメソッドを組み合わせることにより、deviseに定義されているストロングパラメーターをに対し、自分で新しく追加したカラムを指定して含めることができる。
プライベートメソッドの中に使用。
devidseで定義されているpermitメソッドであり、Railsで初めから使用できたpermitメソッドとは別にする
devise_parameter_sanitizer.permit( *:deviseの処理名 , keys: [許可するキー])
####application_controller.rbファイル
全てのコントローラーが継承しているファイル
ここに処理を記述しておくことで、全てのコントローラーで共通となる処理を作ることができる
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
private
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
end
end
before_actionの if
値にメソッド名に指定することで、その戻り値がtrueで会った時にのみ処理を実行するように設定
「deviseにストロングパラメーターを設定するときは特別な記述が必要」
ログインの有無で表示を変えよう
user_signd_in?メソッド
ログインしているかどうかの判定を行う
ユーザーがログインしていればtrue ログアウト状態であればfalseを返す
<% if user_signed_in? %>
<div class="user_nav grid-6">
<%= link_to "ログアウト", destroy_user_session_path, data: { turbo_method: :delete } %>
<%= link_to "投稿する", new_tweet_path, class: "post" %>
</div>
<% else %>
<div class="grid-6">
<%= link_to "ログイン", new_user_session_oath, class: "post" %>
<%= lonk_to "新規登録", new_user_registration_path, class: "post" %>
</div>
<% end %>
DELETEメソッドを使用する際には「data:{turbo_method::delete}」という指定が必要
未ログイン状態のユーザーを転送しよう
リダイレクト
「本来受け取ったパスとは別のパスへ転送する」機能
unless
if
と同様に、条件式の返り値で条件分岐して処理を実行するRubyの構文
falseの時にelseまでの処理を実行する
redirect_toメソッド
リダイレクト処理を行う際に使用するメソッド
コントローラー等での処理が終わった後、アクションに対応するビューファイルを参照せずに、別ページへリダイレクトさせる
redirect_to action: :リダイレクト先となるアクション名
exceptオプション
こちらの後に指定したアクションに対しては、事前処理は実行されません
app/controllers/tweets_controller.rb
class TweetsController < ApplicationController
before_action :set_tweet, only: [:edit, :show]
before_action:move_to_index, except: [:index, :show]
~略~
private
~略~
def move_to_index
unless user_signed_in?
redirect_to action: :index
end
end
これで、before_action
によりmove_to_index
メソッドが先に実行され、indexアクションのindex.html.erbページにリダイレクトしてくれる
indexアクションにアクセスした場合、indexアクションへのリダイレクトを繰り返してしまい、無限ループが起こる。この対策として、except: :index
を付け加える
また、ログインしていなくても、詳細ページに遷移できる仕様にするためにexccept:[:index, :show]としている
unlessでuser_signed_in?
を判定して、その返り値がfalse
だった場合にredirect_toが実行される
ユーザーがログインしていない場合にはindex
アクションが実行されます。