Search code examples
ruby-on-railsrspecdeviserspec-rails

devise model cannot be saved into database


So I have a devise model User, and I added some fields to it like username, address, and so on. The model looks like this:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  attr_accessor :username, :first_name, :last_name, :address

  def profile(username)
    User.find_by(:username => username)
  end
end

Then I am writing RSpec test for this model. However, when I am adding a new user record into the db, it fails. This piece of code looks like this:

require 'rails_helper'

RSpec.describe User, type: :model do
  before(:all) do
    User.create(email: "test@gmail.com", address: "nyc", first_name: "aa", last_name: "bb", username: "lol")
    puts User.count
  end

  after(:all) do
    User.destroy_all
  end

  it 'should return correct record when we query by username' do
    user = User.find_by(username: "lol")
    puts user
    expect(user.address).eql? "nyc"
  end
end

But when I run rails spec, the count of the table is zero, so it seems like the create method fails. Also, it raised an error: "undefined method `address' for nil:NilClass".
The reason why I suspect it is caused by devise is that when I commented out the line started by devise in the User model, the rspec works as normal.
So does anyone know the reason? I have searched relevant posts but none of them has my situation. Thank you.


Solution

  • If you wanna create User with Devise, you need to provide password for your user. Something below might work:

    User.create(
      email: "test@gmail.com",
      address: "nyc",
      first_name: "aa",
      last_name: "bb",
      username: "lol",
      password: "something",
      password_confirmation: "something",
      )
    

    Tips: You don't need to declare in attr_accessor. You can remove it. And use the new hash style

    # old style
    User.find_by(:username => username)
    
    # new style
    User.find_by(username: username)