特定のメールアドレスでユーザーを保存できたらいいなと思ったことはありませんか?
そのような方のために、今回はバリデーションを使い特定のメールアドレスでUserを登録しグループ分けする実装する方法をまとめました。
##目的
特定のグループでのマッチングアプリ
特定のグループに入るにはあらかじめ登録されている特定のメールアドレスのドメインが必要
グループによって表示される投稿内容をかえたいため
##必要なもの
- gem 'devise'
- 正規表現
- sql文
- groupテーブル(親) :name(group_key),:domain
- userテーブル(子) :group_id, :email, :password
##DB設計
name | domain |
---|---|
会社 | company.ac.jp |
大学 | university.ac.jp |
##やること
-
deviseでuserの登録のさいにどこのグループか入力するようにする.
-
あらかじめ作成されているグループに属するようにユーザーを登録
-
登録する際は特定のドメインが設定されており、それに合うメールアドレスしか登録できない
-
グループ別で管理する
##実装
###gemのインストールand設定
bundle install
rails g devise:install
rails g devise User```
formを拡張する必要があるため
`rails g devise:views`
###deviseのモジュールを設定
application_controller
authentication_keysでgroup_keyを認証
```devise :database_authenticatable, :registerable,:recoverable, :rememberable, :trackable, :validatable, authentication_keys: [:email, :group_key]```
###attr_accessorでgroupテーブルのグループ名を参照
userのカラムにはgroup_keyが存在しない。
model/user.rbに記述
`attr_accessor :group_key`
###before_validation
validationがかかる前にメソッドを動かし、group_keyを参照し、group_idをuserのテーブルに保存
model/user.rbに記述
`before_validation :group_key_to_id`
###usersのテーブルにgroup_idを保存する
model/user.rbに記述
```def group_key_to_id
group = Group.where(name: group_key).first
self.group_id = group.id
end```
![スクリーンショット 2016-12-31 15.00.20.png](https://qiita-image-store.s3.amazonaws.com/0/118586/ff84ccf5-9e53-4c58-ac41-4e2ba35b381a.png)
###入力スペースを作成。
生成したdevise/registration/new.htmlに記述
`<%= f.collection_select :group_key, Group.all, :name, :name%>`
collection_select :'保存するカラム', '表示させたいカテゴリーの一覧を配列で表示', 'valueとして扱うカラム名', '表示用のカラム名', 'option'
![スクリーンショット 2016-12-30 23.19.15.png](https://qiita-image-store.s3.amazonaws.com/0/118586/2ca1d5ea-5fca-d5f7-d083-8898e96f85bd.png)
###入力した値を保存
applicationcontrollerに以下をを記述する。
```def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_in, keys:[:group_key])
end```
####validationをカスタマイズ
複雑なバリデーションを書く時はメソッドを作ってしまう。シンボル型でvalidateの後ろにメソッドを記載できる。
```validate :domain_check```
###特定のドメインで登録
groupにあるnameカラムのvalueを取得し、それとuserが入力したemailを正規表現で真偽を判断。偽ならばエラーをはかせる。
```def domain_check
##sql文で特定のドメインをget
sql = "select domain from groups where name='#{group_key}'"
##取得したdomainの配列を除去し、string型で取得
domain=ActiveRecord::Base.connection.select_all(sql).rows.join
##取得したstring型のdomainをemailと正規表現でmatch
unless /#{domain}/ === email
errors[:base] << "学校のemailを登録してください"
end
end```
###まとめ
今回は、deviseを使用していたために、deviseのコントローラーを使用できず、validationで処理をしました。
普段あまり複雑なvalidationを書かないために勉強になりました。
validationにはたくさんのoptionがあるのでまだまだ可能性がありそうです!