Search code examples
ruby-on-railsvalidationtestingrailstutorial.org

Rails password validation fails misteriously while writing unrelated tests


I'm doing Michael Hartl's Rails Tutorial, I'm at chapter 14

Basically I'm building a Twitter clone, to learn Rails.
In this chapter, Users can follow each other.

After writing the first test to check those relationship:

user_test.rb

test "should follow and unfollow a user" do
    michael = users(:michael)
    archer  = users(:archer)
    assert_not michael.following?(archer) 
    michael.follow(archer)                    # LINE OF THE ERROR (rb:100)
    assert michael.following?(archer)
    michael.unfollow(archer)
    assert_not michael.following?(archer)
end

this error popped up:

error

ERROR["test_should_follow_and_unfollow_a_user", UserTest, .192215816000044]
test_should_follow_and_unfollow_a_user#UserTest (6.19s)
ActiveRecord::RecordInvalid:         
ActiveRecord::RecordInvalid: Validation failed: 
  Password can't be blank,        
  Password is too short (minimum is 6 characters)
        app/models/user.rb:102:in `follow'
        test/models/user_test.rb:100:in `block in <class:UserTest>'

it is quite weird because validations were working fine till now, there were even some tests to check their correct behavior (and if I remove the validation on the User model, those tests correctly fire up, but the error in test/models/user_test.rb disappears)

head of models/user.rb

class User < ApplicationRecord
has_many :microposts, dependent: :destroy
has_many :active_relationships,  class_name:    "Relationship",
                                 foreign_key:   "follower_id",
                                 dependent:     :destroy
has_many :following,  through:   :active_relationships,
                      source:    :followed

attr_accessor :remember_token, :activation_token, :reset_token
before_save     :downcase_email
before_create :create_activation_digest

VALID_EMAIL_REGEX = /\A[\d\+\.a-z_-]+@[a-z]+\.[a-z.]+\z/i
validates(:name,     presence: true, length: { maximum: 50 } )
validates :email,    presence: true, length: { maximum: 255 }, 
                     format: { with: VALID_EMAIL_REGEX },                
                     uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 }
has_secure_password

method in model/user.rb that triggered the error

# follows a user
def follow(other_user)
    following << other_user    # LINE OF THE ERROR (rb:102)
end

head of fixtures/users.yml

michael:
  name:             Michael Example
  email:            [email protected]
  password_digest:  <%= User.digest('password') %>
  admin:            true
  activated:        true
  activated_at:     <%= Time.zone.now %>

archer:
  name:             Sterling Archer
  email:            [email protected]
  password_digest:  <%= User.digest('password') %>
  activated:        true
  activated_at:     <%= Time.zone.now %>

other files

all other files can be found on my github page


Solution

  • I finished the same tutorial and in my User model I validated for the password to be as the following:

      validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
    

    Perhaps add allow_nil: true.