I am writing user authentication for a Rails application. Faced with such an error (indicated in the title of the question)

models / user.rb

class User < ActiveRecord::Base attr_accessor :password, :password_confirmation before_save :encrypt_password validates :email, presence: true validates :password, length: {minimum: 6}, confirmation: true protected def encrypt_password self.password_salt = BCrypt::Engine.generate_salt self.password_hash = BCrypt::Engine.hash_secret(password, password_salt) end def self.authenticate(params) user = find_by_email(params[:email]) if user && user.password_hash == BCrypt::Engine.hash_secret(params[:password], user.password_salt) user else nil end end end 

accounts_controller

 class AccountsController < ApplicationController def new @user = User.new end def create @user = User.new(signup_params) if @user.save User.authenticate(params[:email], params[:password]) redirect_to root_path, notice: "Вы успешно зарегистрировались" else render 'new' end end def signin @user = User.new end def authenticate @user = User.authenticate(signin_params) if @user redirect_to root_path, notice: "Вы успешно вошли" else render 'signin' end end private def signup_params params.require(:user).permit(:email, :password, :password_confirmation) end def signin_params params.require(:user).permit(:email, :password) end end 

Some of the routes are responsible for all this:

 resource :account, as: :users do collection do get 'signin', to: 'accounts#signin' post 'authenticate', to: 'accounts#authenticate' end end 

form (haml)

 %h1 Вход = form_for @user, url: authenticate_users_path do |f| %p = f.label :email = f.email_field :email %p = f.label :password = f.password_field :password %p = f.submit 

Why do I get such an error when sending a siging form? How to organize?

    1 answer 1

    The problem is that if authorization fails, you draw the form that is generated for the user ( @user ). In this case, the user does not have. To avoid this error, before drawing the entry form you need to create an object class User

     def authenticate @user = User.authenticate(signin_params) if @user # Пользователь существует(@user не nil и не false) redirect_to root_path, notice: "Вы успешно вошли" else # Пользователя не существует(nil или false) @user = User.new # Создаем объект класса User render 'signin' end end