Deviseの設定手順をまとめてみた。 その1　導入編

RailsでDeviseを使おうと思って、自分なりに手順をまとめてみた。


--- 全体の流れ ---
[その1　導入編](http://qiita.com/itboze/items/ea0d9236d89fa24a7a1c) ←今ココ
[その2　ViewとControllerのカスタマイズ編](http://qiita.com/itboze/items/f991d54ff527edb844d9)
[その3　Deviseの日本語化編](http://qiita.com/itboze/items/a1b532004a9a8a57e296)
[その4　ユーザーIDで、ログイン認証編](http://qiita.com/itboze/items/385d3cd539fc7578b52a) 


まずは、導入編。

### 1. 事前準備

* Railsプロジェクトを作成しておく
* Postfixの設定を済ませておく(ユーザー登録の際、メールを飛ばしたい場合)

### 2. Gemfileに以下を追加

```rb
gem 'devise'
```

### 3. bundle install を実行

```console
$ bundle install
```

### 4. Railsプロジェクトに、deviseをインストール

```console
$ rails g devise:install
```

```
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:

       config.assets.initialize_on_precompile = false

     On config/application.rb forcing your application to not access the DB
     or load models when precompiling your assets.

  5. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===================================================================
```

### 5. rootのURL用のコントローラーを作成

```console
$ rails g controller Home index show
```

### 6. rootのURLをルーティングに設定

* `config/routes.rb`に、以下の内容を記述

```rb
  get 'home/index'             
  get 'home/show'              
  
  root to: "home#index"
```

### 7. メッセージ表示領域を追加

* とりあえずapp/views/layouts/application.html.erbのbodyの一番上に追記
* とりあえず、全ての画面の上部に、
	* ログインしていない場合は、「サインイン」と「ログイン」のリンク
	* ログインしている場合は、「プロフィール変更」と「ログアウト」のリンク
を表示させるようにしています。


```erb
<body>

  <header>
    <nav>
      <!-- user_signed_in? はユーザがログインしているか調べるdeviseのHelperメソッド -->
      <% if user_signed_in? %> 
        <!-- current_user は現在ログインしているUserオブジェクトを返すdeviseのHelperメソッド -->
        <!-- *_path はUserモデルを作成したときに、
        deviseにより自動で作成されてますので、rake routesで確認できます -->
        Logged in as <strong><%= current_user.email %></strong>.
        <%= link_to 'プロフィール変更', edit_user_registration_path %> |
        <%= link_to "ログアウト", sign_out_path %>
      <% else %>
        <%= link_to "サインイン", new_user_registration_path %> |
        <%= link_to "ログイン", new_user_session_path %>
      <% end %>
    </nav>
  </header>

  <p class="notice"><%= notice %></p>
  <p class="alert"><%= alert %></p>
  
  <%= yield %>
</body>
```

* **注意点** : **ログアウト**のリンクタグを以下のように記述すると、ルーティングエラーが発生する。

```erb
<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
``` 

* 上記のエラーを回避するには、`config/initializers/devise.rb`ファイルで、以下の修正をする必要がある。

```rb
config.sign_out_via = :delete
	↓
config.sign_out_via = :get
```

* ただ、上記の修正方法は、あまり良い気がしないので、ログアウトのリンクタグは、`sign_out_path`が無難だと思う。


### 8. メソッドについて

* 認可を必要とするコントローラーの before_action で以下のように指定。
* ユーザーのモデル名が User の場合は以下。

	```rb
before_action :authenticate_user!
	```

* ユーザーがサインインしているかどうかを検証するメソッド。

	```rb
user_signed_in?
	```

* 現在サインインしているユーザーを取得。

	```rb
current_user
	```

* ユーザーのセッション情報にアクセス。

	```rb
user_session
	```

### 9. 認証ユーザー用のModelを作成

* 認証ユーザー用のModel名は任意
* 今回は、`User`とする

```console
$ rails g devise User
```

### 8. サインアップ時に確認メールを出す場合

* db/migrate/nnnnnn_devise_create_users.rbのt.confirmableのコメントを外します。

```rb
      ## Confirmable
      t.string   :confirmation_token
      t.datetime :confirmed_at
      t.datetime :confirmation_sent_at
      t.string   :unconfirmed_email # Only if using reconfirmable
```

* インデックスも有効にする

```rb
    add_index :users, :confirmation_token,   unique: true
```

### 9. ModelをDBに反映

```console
$ rake db:migrate
```

### 10. 認証チェック(アクセス制限)について

* 必要に応じてControllerに認証チェックを追加

```rb
before_filter :authenticate_user!
```

* Homeのshow画面へのアクセス制限を追加する例

```rb
class HomeController < ApplicationController
  # ユーザがログインしていないと"show"にアクセスできない
  before_action :authenticate_user!, only: :show

  def index
  end

  def show
  end
end
```

### 11. メール送信の設定

##### 1. `config/environments/development.rb`

* 必要に応じてtest.rb,production.rbにも追記
* 値は環境に応じて変更する

```rb
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
  
config.action_mailer.raise_delivery_errors = true

 ActionMailer::Base.delivery_method = :smtp
 ActionMailer::Base.smtp_settings = {
   :address => "smtp.gmail.com", # smtpサーバーのホスト名
   :port => 587,
   :authentication => :plain,
   :user_name => "送信元のメールアドレスのアカウント名",
   :password => "メールアカウントのパスワード"
 }
```

##### 2. `config/initializers/device.rb`

```rb
config.mailer_sender = 'xxxxx@xxxx.com'  # 送信元のメールアドレス
```

##### 3. `app/models/user.rb`

* **`confirmable`**を追加

```rb
  devise :database_authenticatable, :registerable,:confirmable,
         :recoverable, :rememberable, :trackable, :validatable
```

### 12. Railsを起動し、動作確認

```console
$ rails s
```

* どうですか？　ここまでうまくできましたかー？