0

I have a problem with my validation of password ! When I set password and password_confirmation to a specific value, no matter what I do it print the error "Password can't be blank". Here is my migration file :

class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :username
      t.string :email
      t.string :password_digest
      t.string :first_name
      t.string :last_name
      t.integer :role_id, :default => 1
      t.timestamps
      t.boolean :newsletter_status
    end
  end
end

My model file :

class User < ActiveRecord::Base
  belongs_to :role
  has_many :article

  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true,
                    length: { minimum: 4 },
                    uniqueness: { case_sensitive: false },
                    format: { with: VALID_EMAIL_REGEX }

  validates :first_name, presence: true,
                         length: { minimum: 3, maximum: 50 }

  validates :last_name, presence: true,
                        length: { minimum: 3, maximum: 50 }

  validates :username, presence: true,
                       length: { minimum: 3, maximum: 30 },
                       uniqueness: { case_sensitive: true }

  validates :password, length: { minimum: 6, maximum: 100 }, allow_nil: true
  has_secure_password
end

My controller file :

class UsersController < ApplicationController
  def new
    @user = User.new
    @user.role_id = 1
  end

  def create
    @user = User.new(user_params)
    @user.role_id = 1
    if @user.save
      flash[:notice] = "L'article à bien été créé"
      redirect_to article_path(@article)
    else
      render 'new'
    end
  end

  private
    def user_params
      params.require(:user).permit(:first_name, :last_name, :username, :email, :password, :password_confirmation, :role_id, :newsletter_status)
    end
end

My view form :

<div class="row">
      <div class="col-md-6 mb-3">
        <%= f.label :password, "Mot de passe" %>
        <%= f.password_field :password, class: "form-control", placeholder: "Mot de passe" %>
      </div>
      <div class="col-md-6 mb-3">
        <%= f.label :password_confirmation, "Confirmation" %>
        <%= f.password_field :password_confirmation, class: "form-control", placeholder: "Mot de passe" %>
      </div>
    </div>

No matter what I do, it can't create a user. If I do in the rails console user = User.new and enter all parameters it still write password can't be blank in errors.full_messages :

2.3.4 :021 > user = User.create(first_name: 'Name', last_name: 'Surname', email: 'email@example.com', username: 'Username', password: 'password', password_confirmation: 'password', newsletter_status: true)                                        
   (0.1ms)  begin transaction
  Role Load (0.3ms)  SELECT  "roles".* FROM "roles" WHERE "roles"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ?  [["email", "email@example.com"], ["LIMIT", 1]]
  User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE "users"."username" = ? LIMIT ?  [["username", "Username"], ["LIMIT", 1]]
   (0.1ms)  rollback transaction
 => #<User id: nil, username: "Username", email: "email@example.com", password_digest: nil, first_name: "Name", last_name: "Surname", role_id: 1, created_at: nil, updated_at: nil, newsletter_status: true>
2.3.4 :022 > user.errors.full_messages
 => ["Password can't be blank"]

I am on rails 5.1.4 and ruby 2.3.3 Thanks !

Léo Coletta
  • 1,099
  • 2
  • 12
  • 24
  • What output for `user = User.create(first_name: 'Name', last_name: 'Surname', email: 'email@example.com', username: 'Username', password: 'password', password_confirmation: 'password')` in rails console? – taras Nov 29 '17 at 21:52
  • it does this : https://pastebin.com/WBmnpKeQ | I'll add this to the question @tbard – Léo Coletta Nov 29 '17 at 22:33
  • looks like the password= method is not called or overwritten., this method is responsible for populating password_digest and it is found empty while validating by rails. try commenting your password validation i.e validates :password .. . the has_secure_password does add validation on it. – Naren Sisodiya Nov 29 '17 at 22:38
  • @NarenSisodiya I commented the has_secure_password and validates :password lines. However, the problem do not go away : when I issue command `User.create(first_name: 'Name', last_name: 'Surname', email: 'email@example.com', username: 'Username', password: 'password', password_confirmation: 'password', newsletter_status: true)` I still have the same errors.full_messages – Léo Coletta Nov 29 '17 at 23:02
  • Do you have any callbacks that are doing validations(before_create or before_save). Does your user model have a password_digest attribute? – ruby_newbie Nov 29 '17 at 23:25
  • Also what is your intention with including `allow_nil: true`? – inveterateliterate Nov 30 '17 at 13:53

2 Answers2

0

Try bumping has_secure_password to be above your validation rules.

If allow_nil: true is meant to be for letting a user update their other information without entering their password, try using allow_blank: true for that instead.

Finally, bcrypt has a max length of 72, according to the docs, so you can drop the max length part of your validation. http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html

-2

The migration file has the issue.

You have not created a row for password.

  • Ok, but is it not supposed to automatically convert password to password_digest. If I do this, I will have a column password, in addition of password_digest wich is strange no ? @Magicwand – Léo Coletta Nov 30 '17 at 10:44