我跟随Ryan Bates的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
- 语句。我的代码是:
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?
有什么想法吗?
答案 0 :(得分:2)
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#===
,后者是一个没有初始条件的完全有效的案例。
答案 1 :(得分:2)
case
/ when
阻止case
/ case some_relatively_expensive_operation()
when :foo
# ...
when :bar
# ...
end
阻止的主要优势 - 以及仅优势 - some_relatively_expensive_operation
中的条件将是只运行一次,只运行一次。
所以在这种情况下:
if some_relatively_expensive_operation() == :foo
# ...
elsif some_relatively_expensive_operation() == :bar
# ...
end
some_relatively_expensive_operation()
只会运行一次,而在这种情况下:
:foo
if
将运行一次(如果是elsif
)或两次(如果是其他的话)。
这不仅仅关系到性能,它还使得条件以后更容易更改,因为您只需要这样做一次,而不是有多少user
/ User
块。
显然,如果你想测试不同的多个条件,这个结构根本不起作用 - 这是你当前代码正在做的事情。是的,你可以用一个lambda来解决这个问题,这是另一个答案所做的,但这完全忽略了这个结构的意义,就像用锤子钉在钉子上一样。
所以你需要做的是向对象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
我们仍然需要检查特殊访客权限案例,可以在主<{1}}之前完成:
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
返回proceedure TForm1.Timer1Timer(Sender: TObject);`
begin
TTask.Run(procedure
var
i: integer;
begin
for i:=0 to 50 do
begin
TThread.Synchronize(TThread.CurrentThread,
procedure
begin
Memo1.Lines.Add(i.ToString);
Sleep(500);
end);
end;
end);
end;
,即使是一行。
答案 2 :(得分:0)
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 / then样式语法或执行以下操作:
case user.role
when :guest
#something
when :admin
#something
#etc...
end
http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-case