Reputation: 1104
If I type a user's username and password, everything works fine, BUT if I type nothing or just the username the following error appears:
First argument in form cannot contain nil or be empty
in
<%= form_for @user, :as => :user, :url => user_sign_in_path(@user), :html => {:class => 'navbar-form', :role => 'login'} do |user_form_builder|%>
app/views/user/sign_in.html.erb:10:in '_app_views_user_sign_in_html_erb__420697496_32907636'
app/controllers/user_controller.rb:23:in 'login'
I think you'll need the controller, route and view:
View:
<%= form_for @user, :as => :user, :url => user_sign_in_path(@user), :html => {:class => 'navbar-form', :role => 'login'} do |user_form_builder|%>
<div class="form-group text-xs">
<%= user_form_builder.text_field :username, :class => 'form-control input-xs', :placeholder => 'eMail or Username'%><br>
<%= user_form_builder.password_field :password, :class => 'form-control input-xs', :placeholder => 'Passwort'%><br>
<div class="checkbox pull-left">
<label class="">
<input type="checkbox"> Angemeldet bleiben
</label>
</div>
<%= user_form_builder.submit 'Anmelden', :class => 'btn btn-success btn-xs pull-right'%><br><br>
oder <button type="button" class="btn btn-success btn-xs">Registrieren</button>
</div>
<% end %>
Controller:
class UserController < ApplicationController
def sign_in
@user = User.new
end
def login
username_or_email = params[:user][:username]
password = params[:user][:password]
if username_or_email.rindex('@')
email = username_or_email
user = User.authenticate_by_email(email, password)
else
username = username_or_email
user = User.authenticate_by_username(username, password)
end
if user
flash[:notice] = 'Welcome'
redirect_to :root
else
flash[:error] = 'Unknown user. Please check your username and password.'
render :action => "sign_in"
end
end
def change_pw
end
def forgot_pw
end
def new
end
def sent_pw
end
def signed_out
end
end
Routes:
Calendar::Application.routes.draw do
root "welcome#index"
get "user/change_pw" => "user#change_pw"
get "user/forgot_pw" => "user#forgot_pw"
get "user/new" => "user#new"
get "user/sent_pw" => "user#sent_pw"
get "user/sign_in" => "user#sign_in"
get "user/signed_out" => "user#signed_out"
get "welcome/index"
post "user/sign_in" => "user#login"
end
I can't find the problem.
Upvotes: 0
Views: 600
Reputation: 38645
On failure to authenticate, you are rendering sign_in
action. With render
, as opposed to redirect_to
, the action does not execute; it only renders the action's view.
So, the expected @user
instance variable is not defined in the login
action which is the reason for this error.
Try updating login
action as follows:
def login
...
if user
flash[:notice] = 'Welcome'
redirect_to :root
else
flash[:error] = 'Unknown user. Please check your username and password.'
# Assign user to instance variable for the `sign_in` view!
@user = user
render :action => "sign_in"
end
end
And instead of defining an extra variable, you could choose to replace all local user
variables with instance variables as @user
in your login
action.
Update: The quickest workaround to this problem would be to create a new user with the supplied parameters as follows:
def login
...
if user
flash[:notice] = 'Welcome'
redirect_to :root
else
flash[:error] = 'Unknown user. Please check your username and password.'
# Create new user instance variable for the `sign_in` view!
@user = User.new(params[:user])
render :action => "sign_in"
end
end
Upvotes: 2
Reputation: 53038
Update login
method as below:
def login
username_or_email = params[:user][:username]
password = params[:user][:password]
if username_or_email.rindex('@')
email = username_or_email
user = User.authenticate_by_email(email, password)
else
username = username_or_email
user = User.authenticate_by_username(username, password)
end
if user
flash[:notice] = 'Welcome'
redirect_to :root
else
flash[:error] = 'Unknown user. Please check your username and password.'
@user = User.new ## Set @user instance variable
render :action => "sign_in"
end
end
You are getting error because @user
instance variable is not set in case of authentication failure.
Also, you might want to replace user
with @user
as suggested by Vee.
Otherwise, if you are accessing @user
in case of successful authentication (on root page), then again you'll get error.
Upvotes: 1