我遵循莱恩·贝茨的RC#386授权。Ryan的原始代码如下:
module Permissions
def self.permission_for(user)
if user.nil?
GuestPermission.new
elsif user.is_admin?
AdminPermission.new(user)
else
MemberPermission.new(user)
end
end
end就像预期的那样。
我需要允许的不仅仅是三个授权方案。我需要添加额外的授权角色,如Editor、Moderator、Senior Editor等。我试图通过将其更改为case-statement来实现这一点。我的代码是:
module Permissions
def self.permission_for(user)
case user#.role #TODO: This will eventually be refactored into a role checker...
when user.is_admin?
AdminPermission.new(user)
when user.current_user
MemberPermission.new(user)
else
GuestPermission.new
end
end
end但是,我收到了一个NoMethod错误
when user.is_admin?有什么想法吗?
发布于 2016-03-21 19:41:55
如果您问我case/when块的−,主要的优势是case中的条件将精确地运行一次和一次。
所以在这种情况下:
case some_relatively_expensive_operation()
when :foo
# ...
when :bar
# ...
endsome_relatively_expensive_operation只运行一次,而在本例中:
if some_relatively_expensive_operation() == :foo
# ...
elsif some_relatively_expensive_operation() == :bar
# ...
endsome_relatively_expensive_operation()将运行一次(如果是:foo)或两次(如果是其他东西)。
这不仅关系到性能,而且还使条件以后更容易更改,因为您只需要这样做一次,而不管您有多少if/elsif块,都不需要这样做。
显然,如果您想测试不同的−(这就是当前代码所做的)的多个条件,那么这个结构根本无法工作。是的,你可以用一个lambda来解决这个问题,另一个答案就是这样做,但这完全忽略了这个结构的意义,就像用锤子钉钉子一样。
因此,您需要做的是向对象user添加一个方法,该方法返回一个带有角色的值。我对您的User模型没有洞察力,但这可能很简单:
class User
# [..]
def role
if is_admin?
:admin
else
:member
end
end
end我们仍然需要检查特殊来宾权限情况,这可以在主case之前完成。
def self.permission_for(user)
# No current user - return Guest permissions
return GuestPermission.new unless user.current_user
case user.role
when :admin
AdminPermission.new(user)
when :member
MemberPermission.new(user)
end
end或者,您可以修改User.role以返回:guest。你喜欢什么都行。
现在,您会注意到,这些行实际上看起来非常相似。为什么在这里使用case/when块?我们就不能从user.role构造类名吗?不,我们可以!
# Get instance to the class
klass = Object.const_get "#{user.role.to_s.capitalize}Permission"
# And create it!
klass.new user我们可以做一个两行的方法!
def self.permission_for(user)
return GuestPermission.new unless user.current_user
return Object.const_get("#{user.role.to_s.capitalize}Permission").new user
end如果没有当前用户,User.role甚至返回:guest一行。
发布于 2016-03-21 17:41:10
case user
when ->(u) { u.is_admin? } then AdminPermission.new(user)
when ->(u) { u.current_user } then MemberPermission.new(user)
else GuestPermission.new
end或
case
when user.is_admin? then AdminPermission.new(user)
when user.current_user then MemberPermission.new(user)
else GuestPermission.new
end前者使用Proc#===,后者是一个完全有效的情况,没有初始条件。
发布于 2016-03-21 17:25:04
Case语句检查每个when子句的相等性,例如
case x
when 1
puts "Do something when x === 1."
when "D"
puts "Do something when x === D."
else
puts "Doing nothing"
end因此,对于您的示例,您可能希望保持if/ want样式语法或执行如下操作:
case user.role
when :guest
#something
when :admin
#something
#etc...
end http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-case
https://stackoverflow.com/questions/36137613
复制相似问题