我有一个登录页面,验证可以成功与否。这是页面new.html.erb
:
<%=form_with scope: :session, url: sessions_path, local: true, html: {class: "login-form"} do |f| %>
<%= f.label :email, t("session.new.email") %>
<%= f.email_field :email %>
<%= f.label :password, t("session.new.password") %>
<%= f.password_field :password %>
<%= f.submit t('session.new.login'), class: "submit" %>
<% end %>
它与sessions_controller.rb
相关联,如下所示:
class SessionsController < ApplicationController
def create
# Find the user with the matching email
user = User.find_by(email: params[:session][:email].downcase)
# Check the user exists in DB and that the provided password matches
if user && user.authenticate(params[:session][:password])
# Log the user through the session helper
log_in user
# Redirect to the hive
redirect_to ideas_path
else
# The authentication failed. Display an error message
flash.now[:error] = I18n.t('session.new.invalid_credentials')
# The render is done to reinitiate the page
render :new
end
end
end
在我的routes.rb
中,我只是为了这个目的:
resources :sessions
执行rails routes
时,我有以下声明的路线:
现在我的问题是登录失败了。在我的控制器中,在这种情况下,我在Flash消息中添加一条消息,然后重新呈现相同的页面new.html.erb
。但是在浏览器中,登录请求POST已在网址/sessions
上发送。问题是我浏览器上的当前网址变为/sessions
而不是留在/sessions/new
。这就好像POST请求在我的浏览器中更改了URL。但实际上这只是一个AJAX请求,不是吗?
我发现这个blog post对这种现象有同样的想法(我不是作者)
我找到了一个解决方法,但我更愿意避免使用它并理解bevahior。如果我用下面的方法替换我的路线,这可行:
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
我可以理解为什么会这样:get和post url是相同的,所以浏览器不会更改其URL。
你有什么想法吗?
修改
我终于找到了解决方案。我不确定这是“轨道方式”,但这可以按预期工作。我刚刚更改了控制器以重定向到同一页面,并通过flash请求传输登录失败信息:
def create
# Find the user with the matching email
user = User.find_by(email: params[:session][:email].downcase)
# Check the user exists in DB and that the provided password matches
if user && user.authenticate(params[:session][:password])
# Log the user through the session helper
log_in user
# Redirect to the hive
redirect_to ideas_path
else
# The authentication failed. Display an error message through a flash
# message after redirect to the same page
redirect_to new_session_path, alert: I18n.t('session.new.invalid_credentials')
end
end
答案 0 :(得分:2)
当表单被提交时,浏览器会对/ sessions端点执行常规HTTP POST请求。那里没有AJAX。
您的路线配置方式此POST请求将由您的会话#create action处理。
注意那里的代码。您将看到快乐路径(成功登录)调用redirect_to。如果登录错误,控制器会调用render。
不同之处在于,在第一种情况下,响应是浏览器遵循的302重定向。这就是您在浏览器中看到URL更改的原因。在第二种情况下,响应只有200 OK,浏览器要渲染一堆HTML。该网址不会发生变化,因为浏览器未被指示导航到其他位置。
如果您有兴趣,请点击浏览器中的extensive explanation of how redirects work。