devise でグループ登録機能を追加してみた

今回初めての試み。
ユーザー登録機能とは別にdeviseを使ってグループ登録機能の実装をしてみた。

### やりたい事
* deviseを使用してグループ登録機能（新規登録、ログイン）を実装
* 新規登録にはグループ名とパスワードが必要（今回emailは必要なしとする）

### 前提
* 既にdeviseを使用してユーザー機能は実装済み


### グループのモデル作成
まず初めに、ユーザーとグループのログイン画面を別々にしたいので、下記を入力。

```ruby:config/initializers/devise.rb
# ==> Scopes configuration
  # Turn scoped views on. Before rendering "sessions/new", it will first check for
  # "users/sessions/new". It's turned off by default because it's slower if you
  # are using only default views.
  config.scoped_views = true  # falseからtrueに変更


  # Configure the default scope given to Warden. By default it's the first
  # devise role declared in your routes (usually :user).
  # config.default_scope = :user

  # Set this configuration to false if you want /users/sign_out to sign out
  # only the current scope. By default, Devise signs out all scopes.
  config.sign_out_all_scopes = false  #　　trueからfalseに変更
```

ターミナルで以下を実行。

```:ターミナル
rails g devise　group
```
### email以外で新規登録を可能にする
ユーザー新規登録はemailあり、グループ新規登録はemail無し（グループ名を代用）にしたいので、下記を入力。
※両方ともemail無しにしたい場合は、別の記述方法があるらしい

```ruby:app/models/group.rb
class Group < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :authentication_keys => [:groupname]  # 追記

# 以下も追記
  def email_required?
    false
  end

  def email_changed?
    false
  end
end
```
さらにバリデーションも付け加える。

```ruby:app/models/group.rb
class Group < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :authentication_keys => [:groupname]  

# バリデーション追記
validates :groupname, presence: true
  VALID_PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i
  validates :password, length: { minimum: 6 }, format: { with: VALID_PASSWORD_REGEX }, on: :create
  validates :note,  length: { maximum: 1000 }


  def email_required?
    false
  end

  def email_changed?
    false
  end
end
```

さらに登録時に送信する値を渡すために、コントロールにも記述を加える。

```ruby:registrations_controller.rb
# frozen_string_literal: true

class Groups::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]  # コメントアウトを外す
  # before_action :configure_account_update_params, only: [:update]

# 中略

  # If you have extra params to permit, append them to the sanitizer.
# 以下３行のコメントアウトを外し、[:attribute]を[:groupname]に変更
  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:groupname])
  end

#　以下省略
```

以上が終わったら、ターミナルで``rails db:migrate``を実行。


### エラー発生
するとエラーが発生した。
```:エラー内容
Mysql2::Error: Key column 'email' doesn't exist in table
migrate/xxxxxxxx_devise_create_groups.rb:41:in `change'
```

エラー文にはxxxxxxxx_devise_create_groups.rbの41行目を変更しなさいと書かれている。

該当箇所を確認。
```ruby:xxxxxxxx_devise_create_groups.rb
     ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      t.timestamps null: false
    end

    #add_index :groups, :email,                unique: true  # ４１行目のここをコメントアウトする
    add_index :groups, :reset_password_token, unique: true
    # add_index :groups, :confirmation_token,   unique: true
    # add_index :groups, :unlock_token,         unique: true
  end
end
```
再度``rails db:migrate``を実行。
なんとか成功！

あとは中間テーブル「group_usersテーブル」を作成して、userテーブルと紐つければ完成！！