尝试方法的更好替代方法

Better alternative to try method

我想要一段干净的代码,但我觉得这感觉很笨拙。

有更好的方法吗?

User.try(:profile).try(:settings).try(:card).try(:options)

如果我删除 try 方法,我会得到 nil 方法错误。

是否有另一段代码做类似的事情:

User.try(:profile,:settings, :card, :options)

如果您使用的 Ruby 版本大于 2.3,则可以改用安全运算符。例如,

User.profile&.settings&.card&.options

是不是很整洁?

从 ruby 2.3.0 开始,您可以使用 &. 方法代替 try:

User&.profile&.settings&.card&.options

但是你应该避免这样的事情。

当您向可能 return nil 的对象发送消息时,或者当对象不响应该消息时,这是您应该自行解决的问题。使用 try 只会加剧问题,就像 nil-checking 一样。 编写行为一致的一致接口。

纯属娱乐

自己动手:

# concerns/deep_try.rb

module DeepTry
  def deep_try(*methods)
    methods.reduce(self) { |receiver, method| receiver.try(method) }
  end
end

# user.rb (or anywhere else you want it)
extend DeepTry

这样您就可以安全地调用以下内容:

User.deep_try(:profile, :settings, :card, :options)

您还可以在实例级别使用:

@user.extend(DeepTry).deep_try(:profile, :settings, :card, :options)

我知道这是左派,但你知道,思维的多样性。

我已经创建了(非常小的)漫不经心的 gem 允许在担心错误的情况下执行代码。使用此 gem 代码将如下所示:

insouciant(nil) { User.profile.settings.card.options }

稍微添加 "benefit" 捕获所有标准错误,而不仅仅是 nil 方法错误。 nil 值在出错时被 returned。如果在您的应用程序中更有意义,您可以将其替换为其他值。

完全省略参数将return错误消息作为字符串。