[英]Rails/Ruby extract if block to helper or guard
In my Rails app I need to implement authentication for web app, I need to use an external resource to make it work.在我的 Rails 应用程序中,我需要为 web 应用程序实现身份验证,我需要使用外部资源才能使其工作。 To do so I'm using custom Devise Strategies.
为此,我使用自定义 Devise 策略。 After a tremendous amount of work, I finally managed to implement a code that covers all scenarios - the code is working but unfortunately my eyes bleed when I see the code below:
经过大量的工作,我终于设法实现了一个涵盖所有场景的代码 - 代码正在运行,但不幸的是,当我看到下面的代码时,我的眼睛在流血:
module Devise
module Strategies
class AwareLogin < Authenticatable
def authenticate!
# some logic
# (...)
if login.valid_password?(password) && aware_response.success?
success!(login)
elsif login.valid_password?(password) && !aware_response.success?
success!(login)
elsif login.id.nil? && aware_response.success?
login.set_user_tokens(aware_response)
success!(login)
elsif !login.valid_password?(password) && !aware_response.success?
raise ActiveRecord::Rollback
elsif !login.valid_password?(password) && aware_response.success?
fail!(:aware_auth)
end
rescue SupervisorRollback => s
@user_to_rollback = s.user_id
raise ActiveRecord::Rollback
end
end
end
end
end
end
Is there any way to replace that if block by something clearer like guard or even maybe external helper instead?有没有办法用更清晰的东西代替它,比如警卫,甚至可能是外部助手?
You can consolidate the logic a bit but given that the branches perform different actions you will still need some of the branching.您可以稍微整合一下逻辑,但鉴于分支执行不同的操作,您仍然需要一些分支。
My recommended consolidation我推荐的合并
def authenticate!
begin
if login.valid_password?(password) || (set_token = login.id.nil? && aware_response.success?)
login.set_user_tokens(aware_response) if set_token
success!(login)
else
aware_response.success? ? fail!(:aware_auth) : raise(ActiveRecord::Rollback)
end
rescue SupervisorRollback => s
@user_to_rollback = s.user_id
raise ActiveRecord::Rollback
end
end
Reasoning:推理:
aware_response.success?
aware_response.success?
; .login?valid_password?(password)
we have simply added an or condition to the first branch and to conditionally set the token if this condition is true.login?valid_password?(password)
我们只是简单地在第一个分支中添加了一个 or 条件,如果这个条件为真,则有条件地设置令牌login.valid_password?(password)
is true in the first branch thus reaching this branch means it is false.login.valid_password?(password)
是否为真,因此到达该分支意味着它为假。 Now the only difference is how we respond to aware_response.success?
aware_response.success?
which I just converted to a ternary. Note: There may be uncovered scenarios in your original example, due to the fact that there is no else
.注意:由于没有
else
,您的原始示例中可能存在未发现的场景。 Theoretically login.id.nil? &&.aware_response?success?
理论上
login.id.nil? &&.aware_response?success?
login.id.nil? &&.aware_response?success?
is uncovered and other mutations of such;被发现和其他突变; however I am unfamiliar with the possible options in this specific case.
但是我不熟悉这种特定情况下的可能选项。 My solution will cover these additional scenarios but possibly not as intended, for example:
login.id.nil? &&.aware_response?success?
我的解决方案将涵盖这些额外的场景,但可能与预期不符,例如:
login.id.nil? &&.aware_response?success?
login.id.nil? &&.aware_response?success?
could result in nil
using your branching whereas it will result in raise(ActiveRecord::Rollback)
under mine.使用你的分支可能会导致
nil
,而它会导致我的raise(ActiveRecord::Rollback)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.