我正在构建一个rails应用程序,它根据用户是否完成了某些测验而有很多变化。当用户登录时,一切正常,但我只是尝试注销,我在这行代码上得到NoMethodError
:
<% if current_user.per_quiz.nil? %>
基本上,如果用户已完成per_quiz
,则会转到一个页面(edit
视图),如果他们没有,则会转到其他页面(new
视图) 。唯一改变的是我退出的事实,所以我只能假设这是导致错误的原因。我是否需要添加某种if语句来解释没有用户登录的状态?我应该如何根据Ruby最佳实践修复此错误?
答案 0 :(得分:2)
那是因为当没有用户登录时current_user为nil。如果你将在nil上调用某些方法,它将抛出NoMethodError
。
我假设您在视图中提供了代码。因此,您可以检查用户是否已登录。
<% if user_signed_in? %>
# do smth with user quizzes
<% else %>
# do something else
<% end %>
但最好的方法是在控制器中使用filter之前使用,不允许匿名者查看该页面。
以下是使用Rails和devise的示例应用程序。 https://github.com/RailsApps/rails-devise
希望有所帮助。
答案 1 :(得分:2)
您只需在检查current_user
之前检查是否设置了per_quiz
。您可以通过查询current_user.nil?
:
<% if !current_user %>
<p> You must be logged in to do anything useful. Please go login</p>
<% elsif !current_user.per_quiz %>
<p>Cool quiz stuff goes here...</p>
<% else %>
您可能真正想要的是让已注销的用户转到其他位置,例如主页或登录页面。要做到这一点,您需要为控制器做一些简单的事情。我将假设控制器被称为'QuizzesController',因为你没有在控制器代码中包含你的控制器代码。
以下是如何操作:
class QuizzesController < ApplicationController
# Other devise authentication logic goes here...
before_action :authorize_user!
# Your actions go here...
private
def authorize_user!
if !current_user
redirect_to '/', notice: "You must be logged in to access to this page"
end
end
end
这样做是安装一个“before_action”处理程序,该处理程序将检查用户是否已登录,然后让他们在此控制器中执行任何操作。如果他们没有登录,您可以在任何地方重定向他们。
请注意,有时候,只有某些行为才需要这种治疗。在这种情况下,您可以使用:only
或:except
选项指定要处理或未处理的操作。它看起来像这样:
before_action :authorize_user!, only: [ :new, :edit, :create ]
或者像这样:
before_action :authorize_user!, except: :list
这将为您提供更大的灵活性来管理等式的授权部分,其中devise
处理身份验证部分。
答案 2 :(得分:1)
我不确定这是否是“正确的”Ruby方式,但我最终找到的方法是将其更改为if / elsif / else语句:
<% if current_user.nil? %>
...
<% elsif current_user.bal_quiz.nil? %>
...
<% else %>
...
<% end %>
在我发布问题之前,可能应该已经弄明白了,但是我(并且仍然)有兴趣看看是否有更好或更“Ruby”的方式来做这件事。