Gem devise ユーザー認証機能の作成
世の中の多くのアプリケーションにはユーザー認証機能が備えられています。
投稿したり購入、いいねなどはユーザーを識別して行われるからです。
そこで、Railsを用いたアプリケーションにユーザー認証機能を追加してみます。
目次
- Scaffoldで簡易アプリケーションの作成
- Gem deviseの導入
- ログイン・ログアウトの実装
- ログインユーザー・ゲストユーザーの権限設定
- ユーザーと投稿の関連付け
- 完成ソースコード
1. Scaffoldで簡易アプリケーションの作成
まずはじめにScaffoldを用いて投稿アプリケーションを作成します。
以下を参考にして作成します。
2. Gem deviseの導入
まずはGemfileにdeviseに記載し、bundle installを行います。
...追記
gem 'devise'
$ bundle
そして、deviseをインストールし、モデル(nameを追加)を作成していきます。
$ rails g devise:install
$ rails g devise User name:string
Userモデルにnameカラムを追加しました。
deviseはデフォルトでemailとpasswordのユーザー認証となっています。
これから名前でログインできるよう設定をしていきます。
まずは、deviseのviewとcontrollerを作成していきます。
$ rails g devise:views users
$ rails g devise:controllers users
ルーティングを編集します。
...編集
devise_for :users
↓
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
viewを編集します。
...編集
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
↓
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true, autocomplete: "name" %>
</div>
...追記
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true, autocomplete: "name" %>
</div>
nameを許可するため、deviseの設定ファイルを編集します。
...編集
# config.authentication_keys = [:email]
↓
config.authentication_keys = [:name]
この設定を行うと、emailが許可されなくなってしまうので、許可の設定をします。
...追記
before_action :configure_permitted_parameters,if: :devise_controller?
private
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up,keys:[:email, :name])
end
3. ログイン・ログアウトの実装
deviseの導入はできました。
ここからはトップページにログインボタン・新規登録ボタン、
ログインしたらログインボタンを表示します。
...追記(bodyタグの直下)
<header>
<nav>
<ul>
<% if user_signed_in? %>
<li><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></li>
<% else %>
<li><%= link_to "新規登録", new_user_registration_path %></li>
<li><%= link_to "ログイン", new_user_session_path %></li>
<% end %>
</ul>
</nav>
</header>
ここまでできたらアプリケーションを起動し、試してみましょう。
新規登録・ログイン・ログアウトできることが確認できたと思います。
4. ログインユーザー・ゲストユーザーの権限設定
ここからはログインユーザーの権限を設定していきます。
ログインしていない状態でurlを叩くとログインページにリダイレクトされてしまうことがあると思います。
その機能を実装していきます。
利用するのはdeviseに備わっている以下のメソッドです。
before_action :authenticate_user!
この1文をコントローラに記述するのみです。
では記述していきましょう。
...追記
before_action :authenticate_user!, except: :index
これだけで権限設定の完了です。
この一行でpostsコントローラのindexアクション以外のアクションに遷移した時に、ログインしていなければログインページに遷移させます。
except(あるアクション以外に適用)を利用しましたが、only(あるアクションだけに適用)やonly, except両方指定しなくても大丈夫です。
ここまでできたらログインしない状態でhttp://localhost:3000/posts/1にアクセスしてみましょう。
ログインページに遷移しましたか?
5. ユーザーと投稿の関連付け
さて、ユーザー認証機能・投稿機能は完成しました。
この段階だと誰がどの投稿をしたのかが、判別できません。
自分の投稿を他の人が編集できてしまったり、自分の投稿がどの投稿だったか記憶できていません。
ここからはユーザーと投稿を結びつけていきます。
Railsでモデル間の関連付けをするのは容易です。
今回は一人のユーザーに対して複数(0以上)の投稿が存在しうるので、
関係は1:Nとなります。
その関連付けの定義を行なっていきます。
また、Nの方に1のidを格納しないと関連付けが行えないため、Postモデルにuser_idカラムを追加します。
$ rails g migration AddColumnToPosts user_id:integer
$ rails db:migrate
...追記
belongs_to :user
...追記
has_many :posts
設定できたので試しに投稿してみるとUser must existというエラーが出ます。
投稿する時にuser_idを指定しないといけないので、コントローラも編集します。
def create
...追記
@post.user_id = current_user.id
これで投稿ができるようになったと思います。
これ以降のカスタマイズは皆さんにお任せします。
ユーザー詳細ページを作成したり、投稿したユーザーでなければ編集できない機能を足すのも良いと思います。
アイデア次第なので、色々試してみてください。
補足
投稿者しか投稿の編集・削除が行えないようにします。
...編集
<% if post.user == current_user %>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
def edit
post = Post.find(params[:id])
if post.user != current_user
redirect_to root_path
end
end