概要
Railsアプリにて、ログイン機能を実装するためにgem 'devise'を利用。
users/sign_upからユーザーの新規登録を行ったところエラーが発生した。
エラー文
ArgumentError in Users::RegistrationsController#create
wrong number of arguments (given 0, expected 1)
app/controllers/users/registrations_controller.rb:13:in `create'
def create
@user = User.new(user_params)
if @user.save
redirect_to @user, notice: 'User was successfully created.'
else
render :new
end
wrong number of arguments (given 0, expected 1)は
引数が1つ渡されるはずなのに0になってますよ。ということでコントローラーでcreateアクションがうまくできていない。
結論
has_secure_password password_digestを使っていたから。
devise導入時はhas_secure_password password_digestを使ったセキュアパスワード設定は行わない。
代わりにencrypt_passwordをテーブルカラムに追加することでセキュアパスワード設定ができる。
今回の解決までの流れ
参考:http://ja.voidcc.com/question/p-zenkcgoo-cv.html
調べるとhas_secure_passwordがいらないという情報があったので、userモデルから消しました。
すると、同じようにユーザーの新規登録をすると異なるエラーメッセージが出ました。
password_digestについてエラーが出ている模様。
ActiveRecord::NotNullViolation in Users::RegistrationsController#create
PG::NotNullViolation: ERROR: null value in column "password_digest" violates not-null
constraint DETAIL: Failing row contains (5, test, test@a.com, test@a.com, null, null,
2020-01-21 01:37:23.23543, 2020-01-21 01:37:23.23543,
$2a$11$mFFmw7JD8nrrm3hbz/LUQeFwRPYjjBNKIRAjVuRBNXUM57v2JeeI6, null, null, null).
: INSERT INTO "users" ("name", "email", "profile", "created_at", "updated_at",
"encrypted_password") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"
password_digestはdevise導入前にセキュアパスワード設定のために用意していたカラムです。
調べてみるとdeviseを使用するときはdeviseがpassword_digestの代わりにencrypt_passwordを作ってくれるので、password_digest`はいらないことがわかりました。
確かにdeviseの導入を行っている際にコマンド
$ rails generate devise user
を実行し、作られるマイグレーションファイルにencrypt_passwordが入っていました。
class AddDeviseToUsers < ActiveRecord::Migration[5.2]
def self.up
change_table :users do |t|
## Database authenticatable
t.string :encrypted_password, null: false, default: ""
(省略)
end
今回はこのままマイグレーション実行していたのですが、既にusersテーブルにpassword_digestカラムがあったため上書きされず、encrypted_passwordは反映されてませんでした。
encrypted_passwordについて調べずにマイグレーション実行していたことを反省・・・
ということで、password_digestカラムを削除してから、マイグレーションをやり直してエラーは解決しました。
もう一度結論ですが、deviseを利用してパスワードをハッシュ化し、セキュアパスワード設定をするにはカラムにpassword_digestではなくencrypt_passwordを使うことになります。
他にもusers/newでcreateされるユーザーはdevise管理化の
controllers/users/registrations_controller.rbのnewやcreateメソッドに従って挙動するので、
controllers/users/users_controller.rbのnewやcreateメソッドは不要になるなど
deviseを実装することで不要になるものはいくつかあります。