Rails 上的 Ruby 在重定向到 root_path 或 login_path 时抛出错误
Ruby on Rails throws error wihen redirects to root_path or login_path
我制作了一个简单的应用程序,它与数据库交互并在对用户进行身份验证和授权后在其中执行 CRUD 操作。它曾经在只有一个 table 的情况下工作,但是一旦我开始使用嵌套关系和身份验证机制,我就会收到错误消息。到目前为止,我认为我做的一切都是对的。这是错误的屏幕截图:
这是我的 routes.rb:
Rails.application.routes.draw do
root to: "todo_lists#index"
resources :todo_lists do
resources :todo_items
end
resources :sessions, only: [:new, :create, :destroy]
get "/login" => "sessions#new", as: "login"
delete "/logout" => "sessions#destroy", as: "logout"
end
我的会话控制器:
class SessionsController < ApplicationController
def new
end
def create
@user = User.find_by(username: params[:username])
@password = params[:password]
end
if @user && @user.authenticate(password)
session[:user_id] = @user.id
redirect_to root_path, notice: "Logged in successfully"
else
redirect_to login_path, alert: "Invalid Username/Password combination"
end
def destroy
reset_session
redirect_to login_path, notice: "You have been logged out"
end
end
哦,我修改了 ApplicationController,所以路由应该仍然有效:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :ensure_login
helper_method :logged_in?, :current_user
protected
def ensure_login
redirect_to login_path unless session[:user_id]
end
def logged_in?
session[:user_id]
end
def current_user
@current_user ||= User.find(session[:user_id])
end
end
您是否尝试过在 SessionsController
中使用 root_url
而不是 root_path
?
HTTP 在执行 302 重定向时需要完全限定的 URL。 _url
方法提供绝对路径,包括协议和服务器名称。 _path
方法提供了一个相对路径,同时假定与当前 URL.
相同的服务器和协议
尝试切换到 root_url
,如果有任何变化请告诉我!
编辑: 我建议使用绝对路径的原因是因为在您添加另一个 [=34] 之前,您提到重定向仅使用一个 table 就可以正常工作=] 和嵌套路由。
编辑: 我注意到的另一件事是下面的身份验证块没有像您期望的那样放置在 sessions#create
路由中。
if @user && @user.authenticate(password)
session[:user_id] = @user.id
redirect_to root_path, notice: "Logged in successfully"
else
redirect_to login_path, alert: "Invalid Username/Password combination"
end
它存在于方法之外是否有原因?尝试将其移回创建路线内。
您的重定向逻辑在方法块之外:
if @user && @user.authenticate(password)
session[:user_id] = @user.id
redirect_to root_path, notice: "Logged in successfully"
else
redirect_to login_path, alert: "Invalid Username/Password combination"
end
该代码应该在 create
方法的最终 end
之前
我认为代码不在create
方法中,并且root_path不是class方法,是实例方法:
class SessionsController < ApplicationController
def new
end
def create
@user = User.find_by(username: params[:username])
@password = params[:password]
end # <--- here create method finish. Where this end comes from?
if @user && @user.authenticate(password)
session[:user_id] = @user.id
# root_path is defined for an instance
# of a controller, not for the class
redirect_to root_path, notice: "Logged in successfully"
else
redirect_to login_path, alert: "Invalid Username/Password combination"
end
def destroy
reset_session
redirect_to login_path, notice: "You have been logged out"
end
end
我制作了一个简单的应用程序,它与数据库交互并在对用户进行身份验证和授权后在其中执行 CRUD 操作。它曾经在只有一个 table 的情况下工作,但是一旦我开始使用嵌套关系和身份验证机制,我就会收到错误消息。到目前为止,我认为我做的一切都是对的。这是错误的屏幕截图:
这是我的 routes.rb:
Rails.application.routes.draw do
root to: "todo_lists#index"
resources :todo_lists do
resources :todo_items
end
resources :sessions, only: [:new, :create, :destroy]
get "/login" => "sessions#new", as: "login"
delete "/logout" => "sessions#destroy", as: "logout"
end
我的会话控制器:
class SessionsController < ApplicationController
def new
end
def create
@user = User.find_by(username: params[:username])
@password = params[:password]
end
if @user && @user.authenticate(password)
session[:user_id] = @user.id
redirect_to root_path, notice: "Logged in successfully"
else
redirect_to login_path, alert: "Invalid Username/Password combination"
end
def destroy
reset_session
redirect_to login_path, notice: "You have been logged out"
end
end
哦,我修改了 ApplicationController,所以路由应该仍然有效:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :ensure_login
helper_method :logged_in?, :current_user
protected
def ensure_login
redirect_to login_path unless session[:user_id]
end
def logged_in?
session[:user_id]
end
def current_user
@current_user ||= User.find(session[:user_id])
end
end
您是否尝试过在 SessionsController
中使用 root_url
而不是 root_path
?
HTTP 在执行 302 重定向时需要完全限定的 URL。 _url
方法提供绝对路径,包括协议和服务器名称。 _path
方法提供了一个相对路径,同时假定与当前 URL.
尝试切换到 root_url
,如果有任何变化请告诉我!
编辑: 我建议使用绝对路径的原因是因为在您添加另一个 [=34] 之前,您提到重定向仅使用一个 table 就可以正常工作=] 和嵌套路由。
编辑: 我注意到的另一件事是下面的身份验证块没有像您期望的那样放置在 sessions#create
路由中。
if @user && @user.authenticate(password)
session[:user_id] = @user.id
redirect_to root_path, notice: "Logged in successfully"
else
redirect_to login_path, alert: "Invalid Username/Password combination"
end
它存在于方法之外是否有原因?尝试将其移回创建路线内。
您的重定向逻辑在方法块之外:
if @user && @user.authenticate(password)
session[:user_id] = @user.id
redirect_to root_path, notice: "Logged in successfully"
else
redirect_to login_path, alert: "Invalid Username/Password combination"
end
该代码应该在 create
方法的最终 end
之前
我认为代码不在create
方法中,并且root_path不是class方法,是实例方法:
class SessionsController < ApplicationController
def new
end
def create
@user = User.find_by(username: params[:username])
@password = params[:password]
end # <--- here create method finish. Where this end comes from?
if @user && @user.authenticate(password)
session[:user_id] = @user.id
# root_path is defined for an instance
# of a controller, not for the class
redirect_to root_path, notice: "Logged in successfully"
else
redirect_to login_path, alert: "Invalid Username/Password combination"
end
def destroy
reset_session
redirect_to login_path, notice: "You have been logged out"
end
end