[学習用]Rails5でdeviseを導入してユーザー認証のログイン画面を出すまで。ついでにRails_adminで管理画面も導入しユーザー管理


Rails5にてユーザー認証を導入する。
ログイン、新規登録など出来るようになる。
※一番最後まで実装すると、最終的に Rails_admin＋cancancanで管理画面まで実装してユーザーや投稿の管理一式も実装できる。

#deviseを導入する
##GemFileを編集
GemFile に

```
gem 'devise'
```

これを記述して 

```
$ bundle install
```

インストールする。

##deviseをインストール

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

これで、必要なDeviseがインストールされる。

##ファイルの編集
config/environments/development.rb に
Don't care if the mailer can't send. の下に

```development.rb
# Don't care if the mailer can't send.
config.action_mailer.default_url_option = {host: 'localhost', port: 3000 }
```

これを記述する

#Userモデルを作成

```
$ rails g devise User
$ rails db:migrate
```
rails g devise ＋モデル名(例えば、User,Adminなど)

1回サーバーをCtrl+Cで止めてから再起動させる
そうしないと、エラーが出るので焦る。

##テストユーザーを一括登録
db/seeds.rb に記述する

```seeds.rb
User.create(email: 'admin@test.com', password: 'password')
User.create(email: 'satou@test.com', password: 'password')
User.create(email: 'suzuki@test.com', password: 'password')
User.create(email: 'tanaka@test.com', password: 'password')
User.create(email: 'test@test.com', password: 'password')
```

```
$ rails db:seed
```
このコマンドで上記の5名のユーザーが登録される。
URL+/users/sign-in でログイン画面が表示される

#メモ(後で使う)
##制御:全部できない
controllerに

```sample_controller.rb
before_action :authenticate_user!
```

これを追加するとログインしていないときは、ログインページに自動で飛ばす。使い方のイメージとして、ログインしている人以外に見せたくないページとかを作成できる。

例えば、controllers/post_controller.rb　に記述すれば、投稿ページを非ログイン(非会員)ユーザーには見せなく出来る。

後で使うと思うので、覚えておく。
Admin管理者の場合は、
before_action :authenticate_admin!　にする。
rails g devise Admin(ここの名前)と同じにする様に。

##制御:編集削除できない
ログインしていなくても見れるが、ログインしてないと
編集できない、削除できない様にする為には

```sample_controller.rb
before_action :authenticate_user!, only: [:edit, :update, :destroy]
```

これを記述する
##制御:閲覧だけできる

```sample_controller.rb
before_action :authenticate_user!, only: [:edit, :update, :destroy, :new, :create]
```
これでログインしなくても閲覧だけ出来る状態になる。
よくある制御でたくさん使うと思うので覚えておく。

#ついでに
##名前のカラムを追加する

```
$ rails g migration AddNameToUser name:string
$ rails db:migrate
```
これで Userに名前のカラムを追加できた。
Email＋Password＋名前の登録が出来るはず。

```
$ rails c
> User.all
> exit
```
データベースをコンソールで確認するには rails c　で
確認できる。

##ユーザー名を保存する
controllers/application_controller.rb に追加する

```application_controller.rb
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
    devise_parameter_sanitizer.permit(:account_update, keys: [:name])
  end

```

これで、名前が保存できる様になる。
この後 Veiwsも変更する。


##deviseの Viewsを変更できる様にする
```
$ rails g devise:views User
```
このコマンドで、ログイン周りのViewsを作成できる。
これやらなと、Veiwsに無い。
さらにこれだけだと、いくらViewsを修正しても動かない。
なので下記のコメントを修正すること。

```config/initializers/devise.rb
config.scoped_views = true
```
上記のコメントアウトを外してtrueに変更する。
これでViewsを変更できる様になる。

###変更するViews
views/users/registrations/edit.html.erb

```edit.html.erb
  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
```

views/users/registrations/new.html.erb

```new.html.erb
  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
```

# deviseを日本語化する
```GemFile
gem 'devise'
gem 'devise-i18n'
gem 'devise-i18n-views' #いるかわからないけど入れました。
```

## コマンド実行一覧(手順)★
忙しい時は一気にここから見直せばOKです。

```
$ bundle
$ rails g devise:install
 # 既に上の説明までで作ってあればコマンドの必要は無い。
$ rails g devise user
 # 既に上の説明までで作ってあればコマンドの必要は無い。

$ rails g devise admin
 # adminのモデルを作成する。(NEW)

$ rails g devise:i18n:views user
 # user のViewsを作成(NEW)
 # rails g devise:i18n:views で作るとViewsフォルダがdevise フォルダ名として作成されてしまうので
 # はじめから user を入れておくとフォルダ名がusersで作成してくれる。

$ rails g devise:i18n:views admin
 # admin のViewsを作成(NEW)
 # rails g devise:i18n:views で作るとViewsフォルダがdevise フォルダ名として作成されてしまうので
 # はじめから admin を入れておくとフォルダ名がadminsで作成してくれる。
 # 管理者とユーザーを分けるならはじめからこうした方が都合がいい。

$ rails g devise:controllers users
 # usersのコントローラーを作成
 # 既に上の説明までで作ってあればコマンドの必要は無い。

$ rails g devise:controllers admins
 # adminsのコントローラーを作成
 # 既に上の説明までで作ってあればコマンドの必要は無い。

$ rails g migration AddNameToUser name:string
 # 新規登録時にuser の名前を登録できる様にしておく為、追加
 # 既に上の説明までで作ってあればコマンドの必要は無い。

$ rails g migration AddNameToAdmin name:string
 # 新規登録時にadmin の名前を登録できる様にしておく為、追加
 # 既に上の説明までで作ってあればコマンドの必要は無い。

$ rails db:migrate
```

UserとAdminを分けたので、routes.rb も変更する。


## userとadminを分けたらRoutes設定
```/confgi/routes.rb
Rails.application.routes.draw do

  # devise_for :admins
  # devise_for :users
  devise_for :admins, controllers: {
      sessions:      'admins/sessions',
      passwords:     'admins/passwords',
      registrations: 'admins/registrations'
  }
  devise_for :users, controllers: {
      sessions:      'users/sessions',
      passwords:     'users/passwords',
      registrations: 'users/registrations'
  }
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```

これだけだとまだ日本語にならない。


##Localeを指定する
locale の指定を追加する。

```/config/application.rb
module testname
  class Application < Rails::Application
    config.load_defaults 5.2
    # これの1行を追加する
    config.i18n.default_locale = :ja
  end
end

```


##日本語ファイルと英語ファイルを作成
```
$ rails g devise:i18n:locale ja
$ rails g devise:i18n:locale en
$ rm config/locales/devise.en.yml
```
devise.en.yml は削除する。

/config/locales/devise.views.en.yml
/config/locales/devise.views.ja.yml

に devise: と書かてれいるそれぞれ1ヵ所づつあるので 
users: に修正する。

```/config/locales/devise.views.en.yml
# devise:
users:

```

```/config/locales/devise.views.ja.yml
# devise:
users:

```

これで日本語と英語の言語対応ができた。

### ユーザー部分だけ日本語化している状態

/config/locales/devise.views.en.yml
/config/locales/devise.views.ja.yml
上記の2点を変更するとユーザーログインまわり部分は日本語化されているが
Admin部分は日本語化されてない。

その為、devise.views.ja.yml、devise.views.en.ymlに
users:とuser:　と書かれている部分を丸ごとそれぞれ複製する。
複製したら複製したusers:→admins: と複製したuser:→admin:へ書き換えれば、アドミン上でも日本語化される。　
devise.views.en.yml、devise.views.ja.yml共に行うこと。


##日本語化で参考にしたサイト
[認証機能を実装するdeviseの導入方法](http://www.task-notes.com/entry/ruby/20170620/1497927600)


#deviseで大ハマり
Herokuで何度もリジェトされて大ハマりした話。
devise 使うときシークレットキーが必要な様だ。
※このことを知らずに、Gitを疑い、消しては上げ、消してはあげを繰り返しました。
　シークレットキー必要なんて書きましたが、すでに記載されているので、コメントを外せばOKです。


エラーログにこんな感じでエラーが出ます。

```
Devise.secret_key was not set. Please add the following to your Devise initializer:
       
config.secret_key = '****'
       
Please ensure you restarted your application after installing Devise or setting the key.
```


##これで解決
config/initializers/devise.rb

```devise.rb
config.secret_key = ''
```

シークレットキーの部分をコメント解除すればOKです。
またはキーをいれて再度 git push heroku master　すればOK



# ユーザー管理も一緒に入れる
## Gemfile追加
```Gemfile
gem 'cancancan'
gem 'rails_admin'
```
Gemファイルに2つを追加します。

## コマンド流れ一覧
```
$ bundle
$ rails g cancan:ability
$ rails g rails_admin:install
# このときパスワードを聞かれますが、そのままenterキーでOKです。
# https:～/admin でログインできます。
$ rails g migration AddAdminFlgToUser admin_flg:boolean
# userテーブルにフラグを追加。trueのユーザーのみ管理者として扱います。
# これを入れることで、管理者に指定されていないユーザーは入れません。
$ rails db:migrate
```


## 管理者ユーザーを選択
```
$ rails c
> user = User.find(1)
> user.update_attribute(:admin_flg, true)
```
1番目のユーザーを管理者にしました。
追加した場合はUser.find(1)の数字を変えます。


```config/initializers/rails_admin.rb
# == Devise ==
config.authenticate_with do
  warden.authenticate! scope: :user
end
  config.current_user_method(&:current_user)
 
# == Cancan ==
config.authorize_with :cancan
```
コメントアウトを外します。

## 管理画面権限処理
```app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    if user && user.admin_flg?
      can :access, :rails_admin
      can :manage, :all
    end
  end
end
```
admin_flgによってアクセス権があるかどうかを判定する処理を追加します。


## Herokuへデプロイ後
```
$ heroku run --app testappname rails db:migrate
$ heroku run --app testappname rails c
> user = User.find(1)
> user.update_attribute(:admin_flg, true)
```

◆
これで、ユーザー登録からユーザー管理、投稿内容管理、日本語変換まで一式実装できるようになったと思います。

あとはこれに
- User Showを追加してプロフィールの様なものを追加
- ユーザーEdit更新時にパスワード要求不要に
- carrierwave＋mini_magick＋fog-awsでユーザーにアバターを追加してAWSのS3に保存
- 常時SSL化

この辺いれれば一通り。


◆
1年前にメモ用に書いた内容も追記していったらちょうど1年たってました。
1年もたつとやれること増えるんだなと。

◆
- [プログラミングで挫折しそうなら読むべき記事](https://yokoyamadesuga.com/beginner-programming-learning-school/)
- [初心者がプログラミングで稼ぐことは可能なのか？その方法を解説](https://yokoyamadesuga.com/beginner-programming-earn-method/)