My application has user accounts and the users can log in to view the application. When a user is created by an admin a random password is generated and the user is prompted to change this if this is their first time logging in. Here is my SessionsController:
我的应用程序有用户帐户,用户可以登录查看应用程序。当管理员创建用户时,会生成随机密码,如果这是他们第一次登录,则会提示用户更改此密码。这是我的SessionsController:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(user_name: params[:session][:user_name].to_s.downcase)
if user && user.authenticate(params[:session][:password])
# Log the user in and redirect to the user's show page.
if user.created_at == user.updated_at
# If this is a first time user, then they need to change their password.
log_in user
# This user object is correct at this point, but after this point it is nil.
redirect_to change_password_path(user)
else
log_in user
redirect_to root_path # Redirects to the main page (parts page)
end
else
# Create an error message.
flash.now[:danger] = 'Invalid User Name/Password combination'
render 'new'
end
end
def destroy
log_out
redirect_to login_path
end
end
Before being redirected to the change_password_path, the user object is not nil. Here are my routes for the redirect.
在重定向到change_password_path之前,用户对象不是nil。以下是重定向的路由。
Rails.application.routes.draw do
get 'sessions/new'
resources :parts
resources :users
root "parts#index"
get '/change_password', to: 'users#first_time_password_change'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
end
Once the user is redirected to change their password, the user object is nil and throws an error at _change_password.html.erb. Here is the error and the stack trace:
重定向用户以更改其密码后,用户对象为nil并在_change_password.html.erb处引发错误。这是错误和堆栈跟踪:
undefined method `errors' for nil:NilClass
app/views/users/_change_password.html.erb:2:in `block in _app_views_users__change_password_html_erb__3382781422752759150_70150174196820'
actionview (5.1.4) lib/action_view/helpers/capture_helper.rb:39:in `block in capture'
actionview (5.1.4) lib/action_view/helpers/capture_helper.rb:203:in `with_output_buffer'
actionview (5.1.4) lib/action_view/helpers/capture_helper.rb:39:in `capture'
actionview (5.1.4) lib/action_view/helpers/form_helper.rb:758:in `form_with'
app/views/users/_change_password.html.erb:1:in `_app_views_users__change_password_html_erb__3382781422752759150_70150174196820'
actionview (5.1.4) lib/action_view/template.rb:157:in `block in render'
activesupport (5.1.4) lib/active_support/notifications.rb:168:in `instrument'
actionview (5.1.4) lib/action_view/template.rb:352:in `instrument_render_template'
actionview (5.1.4) lib/action_view/template.rb:155:in `render'
actionview (5.1.4) lib/action_view/renderer/partial_renderer.rb:342:in `block in render_partial'
actionview (5.1.4) lib/action_view/renderer/abstract_renderer.rb:42:in `block in instrument'
activesupport (5.1.4) lib/active_support/notifications.rb:166:in `block in instrument'
activesupport (5.1.4) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.1.4) lib/active_support/notifications.rb:166:in `instrument'
actionview (5.1.4) lib/action_view/renderer/abstract_renderer.rb:41:in `instrument'
actionview (5.1.4) lib/action_view/renderer/partial_renderer.rb:331:in `render_partial'
actionview (5.1.4) lib/action_view/renderer/partial_renderer.rb:310:in `render'
actionview (5.1.4) lib/action_view/renderer/renderer.rb:47:in `render_partial'
actionview (5.1.4) lib/action_view/helpers/rendering_helper.rb:35:in `render'
app/views/users/first_time_password_change.html.erb:1:in `_app_views_users_first_time_password_change_html_erb___4022541670546187761_70150174275000'
actionview (5.1.4) lib/action_view/template.rb:157:in `block in render'
activesupport (5.1.4) lib/active_support/notifications.rb:168:in `instrument'
actionview (5.1.4) lib/action_view/template.rb:352:in `instrument_render_template'
actionview (5.1.4) lib/action_view/template.rb:155:in `render'
actionview (5.1.4) lib/action_view/renderer/template_renderer.rb:52:in `block (2 levels) in render_template'
actionview (5.1.4) lib/action_view/renderer/abstract_renderer.rb:42:in `block in instrument'
activesupport (5.1.4) lib/active_support/notifications.rb:166:in `block in instrument'
activesupport (5.1.4) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.1.4) lib/active_support/notifications.rb:166:in `instrument'
actionview (5.1.4) lib/action_view/renderer/abstract_renderer.rb:41:in `instrument'
actionview (5.1.4) lib/action_view/renderer/template_renderer.rb:51:in `block in render_template'
actionview (5.1.4) lib/action_view/renderer/template_renderer.rb:59:in `render_with_layout'
actionview (5.1.4) lib/action_view/renderer/template_renderer.rb:50:in `render_template'
actionview (5.1.4) lib/action_view/renderer/template_renderer.rb:14:in `render'
actionview (5.1.4) lib/action_view/renderer/renderer.rb:42:in `render_template'
actionview (5.1.4) lib/action_view/renderer/renderer.rb:23:in `render'
actionview (5.1.4) lib/action_view/rendering.rb:103:in `_render_template'
actionpack (5.1.4) lib/action_controller/metal/streaming.rb:217:in `_render_template'
actionview (5.1.4) lib/action_view/rendering.rb:83:in `render_to_body'
actionpack (5.1.4) lib/action_controller/metal/rendering.rb:52:in `render_to_body'
actionpack (5.1.4) lib/action_controller/metal/renderers.rb:141:in `render_to_body'
actionpack (5.1.4) lib/abstract_controller/rendering.rb:24:in `render'
actionpack (5.1.4) lib/action_controller/metal/rendering.rb:36:in `render'
actionpack (5.1.4) lib/action_controller/metal/instrumentation.rb:44:in `block (2 levels) in render'
activesupport (5.1.4) lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
/usr/local/rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/benchmark.rb:308:in `realtime'
activesupport (5.1.4) lib/active_support/core_ext/benchmark.rb:12:in `ms'
actionpack (5.1.4) lib/action_controller/metal/instrumentation.rb:44:in `block in render'
actionpack (5.1.4) lib/action_controller/metal/instrumentation.rb:87:in `cleanup_view_runtime'
activerecord (5.1.4) lib/active_record/railties/controller_runtime.rb:29:in `cleanup_view_runtime'
actionpack (5.1.4) lib/action_controller/metal/instrumentation.rb:43:in `render'
actionpack (5.1.4) lib/action_controller/metal/implicit_render.rb:33:in `default_render'
actionpack (5.1.4) lib/action_controller/metal/basic_implicit_render.rb:4:in `block in send_action'
actionpack (5.1.4) lib/action_controller/metal/basic_implicit_render.rb:4:in `tap'
actionpack (5.1.4) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
actionpack (5.1.4) lib/abstract_controller/base.rb:186:in `process_action'
actionpack (5.1.4) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (5.1.4) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (5.1.4) lib/active_support/callbacks.rb:131:in `run_callbacks'
actionpack (5.1.4) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (5.1.4) lib/action_controller/metal/rescue.rb:20:in `process_action'
actionpack (5.1.4) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
activesupport (5.1.4) lib/active_support/notifications.rb:166:in `block in instrument'
activesupport (5.1.4) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.1.4) lib/active_support/notifications.rb:166:in `instrument'
actionpack (5.1.4) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (5.1.4) lib/action_controller/metal/params_wrapper.rb:252:in `process_action'
activerecord (5.1.4) lib/active_record/railties/controller_runtime.rb:22:in `process_action'
actionpack (5.1.4) lib/abstract_controller/base.rb:124:in `process'
actionview (5.1.4) lib/action_view/rendering.rb:30:in `process'
actionpack (5.1.4) lib/action_controller/metal.rb:189:in `dispatch'
actionpack (5.1.4) lib/action_controller/metal.rb:253:in `dispatch'
actionpack (5.1.4) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (5.1.4) lib/action_dispatch/routing/route_set.rb:31:in `serve'
actionpack (5.1.4) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (5.1.4) lib/action_dispatch/journey/router.rb:33:in `each'
actionpack (5.1.4) lib/action_dispatch/journey/router.rb:33:in `serve'
actionpack (5.1.4) lib/action_dispatch/routing/route_set.rb:834:in `call'
rack (2.0.3) lib/rack/etag.rb:25:in `call'
rack (2.0.3) lib/rack/conditional_get.rb:25:in `call'
rack (2.0.3) lib/rack/head.rb:12:in `call'
rack (2.0.3) lib/rack/session/abstract/id.rb:232:in `context'
rack (2.0.3) lib/rack/session/abstract/id.rb:226:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/cookies.rb:613:in `call'
activerecord (5.1.4) lib/active_record/migration.rb:556:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
activesupport (5.1.4) lib/active_support/callbacks.rb:97:in `run_callbacks'
actionpack (5.1.4) lib/action_dispatch/middleware/callbacks.rb:24:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
web-console (3.5.1) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.5.1) lib/web_console/middleware.rb:20:in `block in call'
web-console (3.5.1) lib/web_console/middleware.rb:18:in `catch'
web-console (3.5.1) lib/web_console/middleware.rb:18:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.1.4) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.1.4) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.1.4) lib/active_support/tagged_logging.rb:69:in `block in tagged'
activesupport (5.1.4) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.1.4) lib/active_support/tagged_logging.rb:69:in `tagged'
railties (5.1.4) lib/rails/rack/logger.rb:24:in `call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
request_store (1.4.0) lib/request_store/middleware.rb:19:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/request_id.rb:25:in `call'
rack (2.0.3) lib/rack/method_override.rb:22:in `call'
rack (2.0.3) lib/rack/runtime.rb:22:in `call'
activesupport (5.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/static.rb:125:in `call'
rack (2.0.3) lib/rack/sendfile.rb:111:in `call'
railties (5.1.4) lib/rails/engine.rb:522:in `call'
puma (3.11.0) lib/puma/configuration.rb:225:in `call'
puma (3.11.0) lib/puma/server.rb:624:in `handle_request'
puma (3.11.0) lib/puma/server.rb:438:in `process_client'
puma (3.11.0) lib/puma/server.rb:302:in `block in run'
puma (3.11.0) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
Here are the first_time_password_change.html.erb
这是first_time_password_change.html.erb
<%= render 'change_password', user: @user %>
<%= logger.info "FUDGE " + @user.class.to_s %>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= link_to 'Show', @user %> |
<%= link_to 'Back', users_path %>
</div>
</div>
Here is the _change_password.html.erb
这是_change_password.html.erb
<%= form_with(model: user, local: true) do |form| %>
<% if user.errors.any? %>
<div id="error_explanation">
<h2 style="color: red;"><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.full_messages.each do |message| %>
<li style="color: red;"><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>Change Password</h1>
<div class="control-group">
<%= form.label :first_name, class: "control-label" %>
<label style="font-size: 20px; font-weight:normal;"> <%= @user.first_name %></label>
</div><br />
<div class="control-group">
<%= form.label :last_name, class: "control-label" %>
<label style="font-size: 20px; font-weight:normal;"> <%= @user.last_name %></label>
</div><br />
<div class="control-group">
<%= form.label :user_name, class: "control-label" %>
<label style="font-size: 20px; font-weight:normal;"> <%= @user.user_name %></label>
</div><br />
<div class="control-group">
<%= form.label :email, class: "control-label" %>
<label style="font-size: 20px; font-weight:normal;"> <%= @user.email %></label>
</div><br />
<div class="control-group">
<%= form.label :privledges, class: "control-label"%>
<label style="font-size: 20px; font-weight:normal;"> <%= @user.privledges %></label>
</div><br />
<div class="control-group">
<%= form.label :new_password, class: "control-label" %>
<%= form.text_field :password, id: :password, class: 'form-control', value: "" %>
</div><br />
<div class="control-group">
<%= form.label :confirm_password, class: "control-label" %>
<%= form.text_field :confirm_password, id: :confirm_password, class: 'form-control' %>
</div><br />
<div class="actions">
<%= form.submit 'Change Password', class: "btn btn-primary" %>
</div>
<br />
</div>
</div>
<% end %>
And Here is the UserController
这是UserController
require 'rubygems'
require 'random_password_generator'
class UsersController < ApplicationController
# Check that the person accessing the application is logged in:
before_action :authenticate_user!
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
@users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
@user = User.new
end
# GET /users/1/edit
def edit
end
# GET /changepassword
def first_time_password_change
end
# POST /users
# POST /users.json
def create
@user = User.new(user_params)
@user.password = RandomPasswordGenerator.generate(10, :skip_symbols => true).to_s
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: @user }
else
format.html { render :new }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
password_is_valid = password_update_is_valid(@user)
respond_to do |format|
if password_is_valid
if @user.update(user_params)
format.html { redirect_to @user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: @user }
else
format.html { render :edit }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
else
format.html { render :edit, notice: '' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
@user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def password_update_is_valid(user)
is_valid = true
user_pass = params[:user][:password]
user_conf = params[:user][:confirm_password]
# Check if the parameters were passed as nil objects
if user_pass.nil? or user_conf.nil?
is_valid = false
user.errors[:base] << "Please fill both the Password and Confirm Password fields."
else
# Check if the password and confirmation passwords are empty
if user_pass == "" or user_conf == ""
user.errors[:base] << "Please fill both the Password and Confirm Password fields."
is_valid = false
end
# Check if the password length is less than 5 characters long
if user_pass.length < 5
user.errors[:base] << "Password must be at least 5 characters long."
is_valid = false
end
# Check if the password and confirm password fields match.
if user_pass != user_conf
user.errors[:base] << "Password and Confirm Password must match."
is_valid = false
end
end
return is_valid
end
private
def set_user
@user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:first_name, :last_name, :user_name, :email, :password, :privledges, :password_digest)
end
end
I am a bit new to rails but the console has some strange output. The first_time_change_password.html.erb is being rendered, followed by the _change_password.html.erb, which is as expected. What is weird is that the first_time_change_password.html.erb is rendered again and the error occurs.
我对rails有点新,但控制台有一些奇怪的输出。正在呈现first_time_change_password.html.erb,然后是_change_password.html.erb,这是预期的。奇怪的是,first_time_change_password.html.erb再次呈现并发生错误。
tarted GET "/change_password.21" for 107.213.96.34 at 2018-01-11 15:48:10 +0000
Cannot render console from 107.213.96.34! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by UsersController#first_time_password_change as
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 21], ["LIMIT", 1]]
Rendering users/first_time_password_change.html.erb within layouts/application
Rendered users/_change_password.html.erb (4.6ms)
Rendered users/first_time_password_change.html.erb within layouts/application (8.1ms)
Completed 500 Internal Server Error in 17ms (ActiveRecord: 0.1ms)
ActionView::Template::Error (undefined method `errors' for nil:NilClass):
1: <%= form_with(model: user, local: true) do |form| %>
2: <% if user.errors.any? %>
3: <div id="error_explanation">
4: <h2 style="color: red;"><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
5: <ul>
app/views/users/_change_password.html.erb:2:in `block in _app_views_users__change_password_html_erb__3382781422752759150_70150174196820'
app/views/users/_change_password.html.erb:1:in `_app_views_users__change_password_html_erb__3382781422752759150_70150174196820'
app/views/users/first_time_password_change.html.erb:1:in `_app_views_users_first_time_password_change_html_erb___4022541670546187761_70150174275000'
I am a bit new to rails and I am studying web development so please have mercy on me.
我对rails有点新,我正在研究Web开发,所以请怜悯我吧。
Also, I am running Rails 5.1.4 on Cloud 9.
另外,我在Cloud 9上运行Rails 5.1.4。
Thank you to everyone who is willing to take the time to look at this and I am sorry about all of the code.
感谢所有愿意花时间看这个的人,我对所有的代码感到抱歉。
3 个解决方案
#1
0
In the UsersController
in the before action before_action :set_user, only: [:show, :edit, :update, :destroy]
add the first_time_password_change
method. before_action :set_user, only: [:show, :edit, :update, :destroy, :first_time_password_change]
As @user
is not set in that method user is nil.
在before action的before_action:set_user中的UsersController中,只有:[:show,:edit,:update,:destroy]添加first_time_password_change方法。 before_action:set_user,only:[:show,:edit,:update,:destroy,:first_time_password_change]由于@user未在该方法中设置,因此用户为nil。
#2
0
Since you asked for an explanation, you were seeing undefined method 'errors' for nil:NilClass
because user
object is actually nil
there. All starts when you call <%= render 'change_password', user: @user %>
without setting @user
in your action first_time_password_change
. Devise makes a helper current_user
available if a user is logged in. Since you make the action available only to authenticated
users with before_action :authenticate_user!
, it's recommended to use current_user
rather than setting up another instance @user
. And you can make use of current_user
in the partial directly without passing it in locals. Hope this will help.
因为你要求解释,你看到nil的未定义方法'errors':NilClass因为用户对象实际上是nil。当您调用<%= render'change_password',user:@user%>而不在您的操作first_time_password_change中设置@user时,全部启动。如果用户已登录,Devise会使帮助程序current_user可用。由于您只对经过身份验证的用户使用before_action:authenticate_user!,因此建议使用current_user而不是设置另一个实例@user。并且您可以直接在部分中使用current_user,而无需在本地传递它。希望这会有所帮助。
#3
0
First of all, this is not a server-side validation this called client-side validation, this matching user data not creating data with validation
首先,这不是服务器端验证,这称为客户端验证,这种匹配的用户数据不会通过验证创建数据
Login
Allow a user to sign in with her/his valid email/username and password. The authentication process happens by matching the email/username and password in the database, allowing the user access to the protected actions only if the given information matches the recorded values successfully. If not, the user will be redirected to the login page again.
允许用户使用她/他的有效电子邮件/用户名和密码登录。通过匹配数据库中的电子邮件/用户名和密码来进行身份验证过程,仅当给定信息与记录值成功匹配时,才允许用户访问受保护的操作。如果没有,用户将再次被重定向到登录页面。
This is not creating data to the database with model validation this is matching data with a database which already exist after that create a session to hold id.
这不是通过模型验证向数据库创建数据,这是与数据库匹配的数据,该数据库在创建会话以保存id之后已经存在。
That's why you need to remove this client-side error code only for login form, after removing this code
这就是为什么在删除此代码后,您只需要为登录表单删除此客户端错误代码
<% if user.errors.any? %>
<div id="error_explanation">
<h2 style="color: red;"><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.full_messages.each do |message| %>
<li style="color: red;"><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
Add flash section which holds your login error like below
添加flash部分,保存您的登录错误,如下所示
<% flash.each do |name, msg| %>
<section class="<%="#{name}" %>-message-section">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="alert-message <%="#{name}" %>-message">
<p><%= msg if msg.is_a?(String) %></p>
<i class="icofont icofont-close"></i>
</div>
</div>
</div>
</div>
</section>
<% end %>
Hope to help
希望能有所帮助
#1
0
In the UsersController
in the before action before_action :set_user, only: [:show, :edit, :update, :destroy]
add the first_time_password_change
method. before_action :set_user, only: [:show, :edit, :update, :destroy, :first_time_password_change]
As @user
is not set in that method user is nil.
在before action的before_action:set_user中的UsersController中,只有:[:show,:edit,:update,:destroy]添加first_time_password_change方法。 before_action:set_user,only:[:show,:edit,:update,:destroy,:first_time_password_change]由于@user未在该方法中设置,因此用户为nil。
#2
0
Since you asked for an explanation, you were seeing undefined method 'errors' for nil:NilClass
because user
object is actually nil
there. All starts when you call <%= render 'change_password', user: @user %>
without setting @user
in your action first_time_password_change
. Devise makes a helper current_user
available if a user is logged in. Since you make the action available only to authenticated
users with before_action :authenticate_user!
, it's recommended to use current_user
rather than setting up another instance @user
. And you can make use of current_user
in the partial directly without passing it in locals. Hope this will help.
因为你要求解释,你看到nil的未定义方法'errors':NilClass因为用户对象实际上是nil。当您调用<%= render'change_password',user:@user%>而不在您的操作first_time_password_change中设置@user时,全部启动。如果用户已登录,Devise会使帮助程序current_user可用。由于您只对经过身份验证的用户使用before_action:authenticate_user!,因此建议使用current_user而不是设置另一个实例@user。并且您可以直接在部分中使用current_user,而无需在本地传递它。希望这会有所帮助。
#3
0
First of all, this is not a server-side validation this called client-side validation, this matching user data not creating data with validation
首先,这不是服务器端验证,这称为客户端验证,这种匹配的用户数据不会通过验证创建数据
Login
Allow a user to sign in with her/his valid email/username and password. The authentication process happens by matching the email/username and password in the database, allowing the user access to the protected actions only if the given information matches the recorded values successfully. If not, the user will be redirected to the login page again.
允许用户使用她/他的有效电子邮件/用户名和密码登录。通过匹配数据库中的电子邮件/用户名和密码来进行身份验证过程,仅当给定信息与记录值成功匹配时,才允许用户访问受保护的操作。如果没有,用户将再次被重定向到登录页面。
This is not creating data to the database with model validation this is matching data with a database which already exist after that create a session to hold id.
这不是通过模型验证向数据库创建数据,这是与数据库匹配的数据,该数据库在创建会话以保存id之后已经存在。
That's why you need to remove this client-side error code only for login form, after removing this code
这就是为什么在删除此代码后,您只需要为登录表单删除此客户端错误代码
<% if user.errors.any? %>
<div id="error_explanation">
<h2 style="color: red;"><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.full_messages.each do |message| %>
<li style="color: red;"><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
Add flash section which holds your login error like below
添加flash部分,保存您的登录错误,如下所示
<% flash.each do |name, msg| %>
<section class="<%="#{name}" %>-message-section">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="alert-message <%="#{name}" %>-message">
<p><%= msg if msg.is_a?(String) %></p>
<i class="icofont icofont-close"></i>
</div>
</div>
</div>
</div>
</section>
<% end %>
Hope to help
希望能有所帮助