我有一个难题要解决。
我想复制title_with_if_statement
方法的结果,但使用title
方法中使用的语法。然而,我不知道在enforce_policy_to_level()
方法中放入什么来实现这一点。
我可以做"title_less_readable",但我发现title方法更可读,因为策略就在顶部,而且由于我将为数百个方法做这件事,我想保持它的干燥和可读性。
有什么建议吗?
这可能吗?它基本上是一个before_action,但使用该方法自己的结果。
class Car
def title
enforce_policy_to_level(1)
# Code that returns the "Car Title" string
"Car Title"
end
def title_less_readable
# Code that returns "Car Title" string
content = "Car Title"
return secure_text(content) unless authorized_to_level?(1)
content
end
def title_with_if_statement
# Code that returns the "Car Title" string
content = "Car Title"
if authorized_to_level?(1)
content
else
secure_text(content)
end
end
private
def enforce_policy_to_level(level)
# Return from title method with the secured result of title method
# if it's not authorized. In this example it would be secure_text('Car Title')
# which output return '---------'
# If if authorized, just continue with how title method would normally return
end
def authorized_to_level?(level)
current_user_level = 1 # Dynamic from user record
current_user_level >= level
end
def secure_text(text)
'X' * text.length
end
end
为什么不做这样的事情?
def title
enforce_policy_to_level(1) do
"Car Title"
end
end
private
def enforce_policy_to_level(level, &block)
if authorized_to_level?(level)
secure_txt yield
else
yield
end
end
考虑分离您的关注点:我会通过创建一个单独的函数来处理授权来实现这一点。
module AuthorizedText
module_function
def secure_text(text, authorized)
return authorized ? text : 'X' * text.length
end
end
在Car
中这样调用:
AuthorizedText.secure_text("Car Title", authorized_to_level(1))
你可以用一种方便的方法来简写:
def secure(level, text)
AuthorizedText.secure_text(text, authorized_to_level(level))
end
以便您的car_title
方法看起来像
def car_title
secure(1, "Car Title")
end
您可以通过定义一个类方法来概括方法包装器,该类方法可以让您执行类似的操作
def car_title
"Car Title"
end
secure :car_title
但我认为这是过度设计的,最终对不是你的人来说可读性较差(可能包括8个月后的你!(。我会避免尝试像这样花哨,尽管这可能很有趣。
此外,如果current_user
和current_user_level
在Car
的上下文之外是有意义的,并且您可能希望在其他地方重用它,那么您可以进一步将身份验证检查方法移动到AuthorizedText
中,如果合适的话:
module AuthorizedText
module_function
def secure_text(text, user, level = 0)
return authorized?(user, level) ? text : 'X' * text.length
end
def authorized?(user, level)
# for example; I don't know what your user object looks like
user.level >= level
end
end