Iggy
Iggy

Reputation: 5251

ArgumentError when using Devise and has_secure_password together

I had a working model prior to adding Devise gem. After I installed Devise and ran rails generate devise User, I started having this error.

Whenever I go to rails console and typed

User.first

or

User.create(username: "Iggy1", email: "[email protected]", password: "helloworld", password_confirmation: "helloworld")

It always returns

  User Load (0.3ms)  SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1
ArgumentError: wrong number of arguments (0 for 1)
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/devise-4.2.0/lib/devise/models/database_authenticatable.rb:146:in `password_digest'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/activemodel-4.2.5/lib/active_model/serialization.rb:108:in `block in serializable_hash'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/activemodel-4.2.5/lib/active_model/serialization.rb:108:in `each'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/activemodel-4.2.5/lib/active_model/serialization.rb:108:in `serializable_hash'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.5/lib/active_record/serialization.rb:17:in `serializable_hash'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/devise-4.2.0/lib/devise/models/authenticatable.rb:114:in `serializable_hash'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/devise-4.2.0/lib/devise/models/authenticatable.rb:120:in `inspect'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/railties-4.2.5/lib/rails/commands/console.rb:110:in `start'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/railties-4.2.5/lib/rails/commands/console.rb:9:in `start'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:68:in `console'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
    from /Users/iggy/.rvm/gems/ruby-2.2.2/gems/railties-4.2.5/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

I kept getting wrong number of arguments (0 for 1) error. I can understand it returns argument error for create method (maybe I specified less parameters), but I don't understand why it shows that error on User.first.

Here is what I have:

users_controller.rb

  ...
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
  end

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end


Schema.rb

  create_table "users", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "password_digest"
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
  end


user.rb (model)

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :lists
  has_many :items, through: :lists
  has_secure_password

There is at least a user in the DB. On localhost index, it shows (I am using serializer):

{"users":[{"id":1,"name":"Iggy1","email":"[email protected]","items":[],"lists":[]}]}

I also has has_secure_password on model. Could that be the cause? I was not sure if has_secure_password is compatible with Devise. How can I fix it so I can create user on rails console?

If you need more code snippet, please let me know!

Upvotes: 1

Views: 2270

Answers (1)

p4sh4
p4sh4

Reputation: 3291

If you look at the docs, you can see what has_secure_password does:

Adds methods to set and authenticate against a BCrypt password. This mechanism requires you to have a password_digest attribute.

You don't have the password_digest attribute, hence the error.

But the real issue is that if you're using Devise, you don't need has_secure_password at all. It is usually used if you want to roll your own authentication, Devise already takes care of encrypting and storing the passwords. Remove it from the model and everything should work.

Upvotes: 8

Related Questions