はじめに
ユーザー管理でお世話になっているdeviseで思わぬエラーにハマり、かなりの時間を溶かしたので備忘録として残しておきます。
環境/Gem(ver)
- Ruby (2.5.1)
- Rails (5.2.4.3)
結論
自分でUserモデルにvalidatesをかける時は気をつけよう。
ちゃんと下調べをして今後実装するようにします。。
前提
devise を bundle install 後、以下のように Userモデルにバリデーションをかけていました。
passwordには7文字以上の制限をかけたいと考えていました。
これで、新規ユーザーの登録は問題なくできていました。
※UserとShopは多対多の関係で中間テーブルにStylistテーブルがあるイメージで実装しています。
(models/user.rb)
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :stylists
has_many :shops, through: :stylists
(省略)
validates :password, presence: true, length: { minimum: 7 }, format: { with: /(?=.*\d+.*)(?=.*[a-zA-Z]+.*)./ }
end
現象
ユーザー(Userモデル)登録後に新規でショップ(Shopモデル)を作成と同時に中間テーブル(Stylistモデル)を作成しようとすると、、エラー。
パラメーターにはちゃんと値が入っているし、何が**「不正な値」なのか、その原因が突き止められず。
また、「新規登録(new/create)はできないが編集(edit/update)はできる」**という状況で、謎が深まり、多くの時間を溶かしました。。
仮説
外部キーのnilを許可すれば解決するのでは?
(models/stylist.rb)
class Stylist < ApplicationRecord
#修正前
belongs_to :shop
belongs_to :user
#修正後
belongs_to :shop, optional: true
belongs_to :user, optional: true
end
・・・ダメでした。
解決策
バリデーションに原因があるのは間違いないので、Userモデルに記述しているvalidatesを一つ一つ解除しながら、挙動を確かめていくと、、
(models/user.rb)
class User < ApplicationRecord
(省略)
validates :password, presence: true, length: { minimum: 7 }, format: { with: /(?=.*\d+.*)(?=.*[a-zA-Z]+.*)./ }
end
↑ validates :password を消したら万事解決でした!!
そして、以下の場所にカスタマイズ内容を書き換えました。
(config/initializers/devise.rb)
class User < ApplicationRecord
(省略)
#修正前
config.password_length = 6..128
#修正後
config.password_length = 7..128
そもそもなぜ中間テーブルを保存する際にエラーを吐き出すのか?謎のままですが、deviseにはデフォルトのバリデーションがあり、自作したバリデーションと良からぬ反応をしたのかなと思います。。(勉強します)
また、以下の記事を参考にさせていただき、カスタマイズをしたところ問題なく動作しております!
参考記事
https://qiita.com/hirokihello/items/862284c60429be5e01cd
https://github.com/heartcombo/devise/wiki/Customize-minimum-password-length