Jan*_*Jan 0 ruby ruby-on-rails case switch-statement
这有什么问题?是的,我可以做一个if else声明,但我想用case语句做.
在我的控制器中
query_limit = case current_user
when nil
return 5
when is_admin?
return 200
when has_role?('registered')
return 20
else
return 5
end
NoMethodError (undefined method `is_admin?' for #<V1::MyController:123123123>):
Run Code Online (Sandbox Code Playgroud)
puts query_limit 当我这样做时,#总是ELSE:
query_limit = case current_user
when nil
return 5
when current_user.is_admin?
return 200
when current_user.has_role?('registered')
return 20
else
return 5
end
Run Code Online (Sandbox Code Playgroud)
模型用户
class User
def is_admin?
self.has_role?('administrator')
end
def has_role?(the_role)
self.roles.any? {|role| role.slug == the_role}
end
end
Run Code Online (Sandbox Code Playgroud)
根据 Ruby 文档:
Case 语句包含一个可选条件,它位于 case 的参数位置,以及零个或多个 when 子句。第一个匹配条件的 when 子句(或评估为布尔真值,如果条件为空)“获胜”,并且它的代码节被执行。
如果指定current_user为 case 条件,则将执行第一个when匹配的表达式current_user。current_user.is_admin?返回一个永远不等于 的布尔值current_user,因此您的第二个示例将始终采用else分支:
case current_user
when nil # current_user != nil, skip condition
return 5
when current_user.is_admin? # current_user != current_user.is_admin?, skip condition
return 200
when current_user.has_role?('registered') # and so on
return 20
else
return 5
end
Run Code Online (Sandbox Code Playgroud)
您的第一个示例已损坏,因为没有is_admin?定义本地方法。case不知道叫is_admin?上current_user在这种情况下。
要修复您的代码,您可以删除案例条件。在这种情况下,when将选择评估为真值的第一个子句:
case # no current_user here!
when current_user.nil? # current_user.nil? is false, skip condition
return 5
when current_user.is_admin? # current_user.is_admin? is truthy, run this one!
return 200
when current_user.has_role?('registered')
return 20
else
return 5
end
Run Code Online (Sandbox Code Playgroud)
方法case是它不会调用你想要放在when子句中的任何方法.相反,它使用将-ed thingy作为参数传递===的when子句case.
换一种说法:
case user
when admin? then 42
end
Run Code Online (Sandbox Code Playgroud)
是不是
42 if user.admin?
Run Code Online (Sandbox Code Playgroud)
但
42 if admin? === user
Run Code Online (Sandbox Code Playgroud)
因为你admin?在控制器中没有方法,所以你得到了一个NoMethodError.
只需简单地重写它if- elsif而不是.
ndn 已经在他的回答中解释了为什么示例中的 case 语句不起作用。
您可以切换到if/elsif块或稍长的when current_user.admin?语法。或者您可以定义一些返回 lambda 的方法:
def is_admin?
->(user) { user.is_admin? }
end
def has_role?(role)
->(user) { user.has_role?(role) }
end
Run Code Online (Sandbox Code Playgroud)
使用这些方法,您可以编写:
query_limit = case current_user
when nil then 5
when is_admin? then 200
when has_role?('registered') then 20
else 5
end
Run Code Online (Sandbox Code Playgroud)