gpt4 book ai didi

ruby-on-rails - 在 Ruby 中,您能否在调用子方法时从主方法决定返回或继续?

转载 作者:行者123 更新时间:2023-12-01 23:05:02 24 4
gpt4 key购买 nike

我正在使用 Pundit我的授权类的 gem,其中根据模型策略检查每个 Controller 操作,以查看用户是否允许操作。

这些方法有时变得非常臃肿和不可读,因为我正在检查一些对象的相当多的东西。

现在我正在考虑重构这些方法,并将每个“验证”放在它自己的方法中:

上一个:

class PostPolicy < ApplicationPolicy

def update
return true if @user.has_role? :admin
return true if @object.owner == user
return true if 'some other reason'

false
end
end

现在理想情况下,我想将其重构为:

class PostPolicy < ApplicationPolicy

def update
allow_if_user_is_admin
allow_if_user_owns_record
allow_for_some_other_reason

false
end

private

def allow_if_user_is_admin
# this would go in the parent class, as the logic is the same for other objects
return true if @user.has_role? :admin
end
end

现在的问题是,mane update 方法将继续运行,即使用户是管理员,因为没有返回。如果我要包括一个返回,那么其他方法将永远不会被评估。 ruby 中有没有一种方法可以执行某种“ super 返回”,以便当用户是管理员时,主要的 update 方法将停止评估?

谢谢!

最佳答案

给定你的例子和这个评论:“......没有原生的方法在 Ruby 中做那种' super 返回'?感觉就像是一种“加薪”但随后产生了积极的结果......也许我可以使用它吗?”

虽然通常有其他方法可以解决被认为“更惯用”的问题,但 ruby​​ 确实有一个 Kernel#throwKernel#catch在浏览大量且可能完全不同的方法和操作时,该实现对于控制流非常有用。

throw 和相应的 catch 将短路 block 的结果,这似乎是您正在寻找的语法。

非常基本的例子:

class PostPolicy 
def initialize(n)
@n = n
end
def update
catch(:fail) do
stop_bad_actor!
catch(:success) do
allow_if_user_is_admin
allow_if_user_owns_record
stop_bad_actor!(2)
allow_for_some_other_reason
false
end
end
end

private

def allow_if_user_is_admin
puts "Is User Admin?"
throw(:success, true) if @n == 1
end

def allow_if_user_owns_record
puts "Is User Owner?"
throw(:success,true) if @n == 2
end

def allow_for_some_other_reason
puts "Is User Special?"
throw(:success,true) if @n == 3
end

def stop_bad_actor!(m=1)
puts "Is a Bad Actor?"
throw(:fail, false) if @n == 6 || @n ** m == 64
end
end

示例输出:

PostPolicy.new(1).update 
# Is a Bad Actor?
# Is User Admin?
#=> true
PostPolicy.new(2).update
# Is a Bad Actor?
# Is User Admin?
# Is User Owner?
#=> true
PostPolicy.new(3).update
# Is a Bad Actor?
# Is User Admin?
# Is User Owner?
# Is a Bad Actor?
# Is User Special?
#=> true
PostPolicy.new(4).update
# Is a Bad Actor?
# Is User Admin?
# Is User Owner?
# Is a Bad Actor?
# Is User Special?
#=> false
PostPolicy.new(6).update
# Is a Bad Actor?
#=> false
PostPolicy.new(8).update
# Is a Bad Actor?
# Is User Admin?
# Is User Owner?
# Is a Bad Actor?
#=> false

关于ruby-on-rails - 在 Ruby 中,您能否在调用子方法时从主方法决定返回或继续?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71084903/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com