我是Rails的新手,并且正在开发一个涉及简单登录功能的练习应用程序。我一直在按照CodeAcademy的书学习教程,但是代码在很多方面都无法正常工作。首先,即使Rails在与会话声明共享的“ if”块内执行其余代码,也不会设置会话(顺便说一句,不返回错误)。
会话控制器:
class SessionsController < ApplicationController
def new
end
def create
@user = User.find_by_username(params[:session][:name])
if @user && @user.authenticate(params[:session][:password])
session[:user_id] = @user.id
redirect_to '/posts'
else
session[:user_id] = nil
flash[:warning] = "Failed login- try again"
redirect_to '/login'
end
end
def destroy
session[:session_id] = nil
redirect_to login_path
end
end
从该问题推断出,我的“ current_user”功能不起作用,这很可能是因为未设置会话。
应用程序控制器:
class ApplicationController < ActionController::Base
def current_user
return unless session[:user_id]
@current_user ||= User.find(session[:user_id])
end
def require_user
redirect_to '/login' unless current_user
end
end
非常感谢您的帮助。让我知道您是否还需要查看其他内容。
注意:我知道我应该使用Devise,并且我打算在以后的项目中进行更严肃的工作。但是,就像我说的那样,这是一个练习/测试应用程序,可以帮助开发我的编码技能,并且在使用像Devise这样的“神奇”瑰宝之前,我希望获得亲自制作登录系统的动手经验。
答案 0 :(得分:0)
我认为错误是session_controller无法找到current_user。
在application_controller中编写以下代码:
class ApplicationController < ActionController::Base
helper_method :current_user
def current_user
return unless session[:user_id]
@current_user ||= User.find(session[:user_id])
end
def require_user
redirect_to '/login' unless current_user
end
end
让我知道它是否有效
答案 1 :(得分:0)
有一些可能的问题。
首先,在调用@current_user
方法之前,不会设置current_user
。正如@Neha所指出的那样,您需要在ApplicationController中添加一个辅助方法,以便您的所有视图都可以访问current_user
方法。将此行添加到您的ApplicationController中:
helper_method :current_user
现在,要诊断问题,让我们进行一些设置,使您可以对会话和current_user有所了解。
首先,在views/layouts/application.html.erb
的{{1}}行之后,添加以下内容:
<= yield %>
然后添加一个新文件<%= render 'layouts/footer' %>
:
views/layouts/_footer.html.erb
现在在每个视图的底部,您可以看到会话的详细信息。
在您的<hr/>
Session:<br/>
<% session.keys.each do |key| %>
<%= "#{key}: #{session[key]}" %><br/>
<% end %>
<br/>
User:<br/>
<%= current_user&.username || '[None]' %>
操作中,找到用户存在潜在的问题。您正在使用sessions#create
,而您可能应该使用params[:session][:name]
。
相切地,销毁会话的正确方法不是将params[:session][:username]
设置为nil,而是使用session[:id]
。因此,您的SessionsController应该如下所示:
reset_session