deviseでユーザー登録ができない時に疑うところ6点


どこまでやったか

  • deviseをインストール
  • モデルを作成
  • マイグレーションファイルにカラムを追加
  • form_withでf.labelとf.text_fieldにusersテーブルのカラム名を入れてフォームを作成した

この状態でフォームに入力してもデータベースに保存されない場合のチェックリストです。
usersテーブルに存在するカラムが何なのか詳しくは省略します。

1. バリデーション

モデルで変な制約をかけていないかみてみましょう。

user.rb
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
         validates :name, presence: true
         validates :profile, presence: true
         validates :occupation, presence: true
         validates :position, presence: true

2. migrationファイルの制約

テーブル作成の際に変な制約をかけていないかみてみましょう。

devise_create_users.rb
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
      t.string :name
      t.text :profile
      t.text :occupation
      t.text :position

3. ストロングパラメーター

deviseはストロングパラメーターが使用できないので、代わりにdevise_parameter_sanitizerを使用しますね。
私はカラムがひとつ抜けてていました。見直しましょう。
具体的には、emailのカラムを許可するのを忘れていたのですが、ターミナルで実行した時この画像のように、emailの後にROLLBACKされていたので何かその辺が怪しいなと気がつきました。

application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [ :email, :encrypted_password, :name, :profile, :occupation, :position])
  end
end

4. アソシエーション

テーブルを一つしか作成していない状態なら関係ありませんが、複数テーブルがある場合はhas_many 複数形,blongs_to 単数系、など

5. passwordのカラム名

最終的にはこれが原因でした。
deviseでのusersテーブルのカラム(デフォルトではencryped_password)ですが、form_withのパスワードとパスワード再入力では、それぞれカラム名をpassword、password_confimationと記述しないといけません。これはpasswordとpassword_confimationが同じかどうかをチェックし、同じならばencryped_passwordに暗号化した文字列を返すという機能がdeviseに実装されているからです。

間違い

        <%= form_with model: @user, url: user_registration_path, local: true do |f| %>

        <div class="field">
          <%= f.label :encryped_password, "パスワード(6文字以上)" %><br />
          <%= f.password_field :encryped_password, autocomplete: "new-password" %>
        </div>

        <div class="field">
          <%= f.label :encryped_password, "パスワード再入力" %><br />
          <%= f.password_field :encryped_password, autocomplete: "new-password" %>
        </div>
以下略

正解

        <%= form_with model: @user, url: user_registration_path, local: true do |f| %>

        <div class="field">
          <%= f.label :password, "パスワード(6文字以上)" %><br />
          <%= f.password_field :password, autocomplete: "new-password" %>
        </div>

        <div class="field">
          <%= f.label :password_confirmation, "パスワード再入力" %><br />
          <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
        </div>
以下略

6. データベース可視化ソフトが原因

以前別のところで発生しましたが、データベースを可視化しているソフトを(私の場合はSequel Pro)再起動したら実は保存されていた、なんてこともあり得ますので確認ください。

以上