ruby 在Rails 2.3.x中处理嵌套关系中的nil(空)值

euoag5mw  于 2023-02-12  发布在  Ruby
关注(0)|答案(4)|浏览(149)

我当前正在处理的项目在视图中包含以下代码:

<%= product.provider.name %>

上面的代码是获取一个产品的“provider”并显示他/她的名字。但是我的问题是当“provider”为空时,这段代码有时会失败。(我知道这有点不寻常,但是因为我使用的是一个遗留数据库,所以会发生这种情况)
为了检查nil验证,我编写了以下代码(在我的ApplicationHelper中)

def t(obj, attr)
    obj.nil? ? "" : obj.send(attr.to_sym)
end

现在我所做的是这样的:

<%= t(product.provider, "name") %>

尽管这样做有效,我还是遇到了另一个问题,我发现了以下代码:

<%= product.provider.provider_type.title %>

这里的问题是,在上面的代码中,“provider”或“provider_type”可以为空。
我所看到的是一个异常处理机制,可以处理任意数量的嵌套关系。
或者这是一个完全错误的处理嵌套关系中nil值的方法?我运行的是Rails2.3.8。

ygya80vv

ygya80vv1#

这是一个常见问题。您可能需要检查以下内容:

示例:

# With try
product.provider.try(:name)
product.provider.try(:provider_type).try(:title)

# With andand
product.provider.andand.name
e7arh2l6

e7arh2l62#

您可以挽救所有异常:

<%= product.provider.provider_type.title rescue nil %>
nfs0ujit

nfs0ujit3#

由于我们可以使用**#try方法或内联处理异常,这种使用方法违反了得墨忒耳定律:* 每个单位对其他单位的了解应有限:仅与当前单位“密切”相关的单位。*
视图应该得到准备好使用的对象/变量,而不是链.所以你可以尝试在模型中使用
delegate**方法,并用帮助器覆盖其他方法.保持你的视图尽可能的干净,从设计者的Angular 看它们.

o2g1uqev

o2g1uqev4#

我是这样解决这个问题的:

class Object
  def unless_nil(default = nil, &block)
    if nil?
      default
    else
      block[self]
    end
  end
end

product.provider.unless_nil(&:name)
product.provider.unless_nil(&:provider_type).unless_nil(&:title)
product.provider.unless_nil("Not specified", &:name)

拥有Object#unless_blankArray#unless_emptyHash#unless_empty也相当方便。

    • 已添加:**

同时,在某些情况下使用全块甚至更方便:

some_variable = 
  product.provider.unless_nil do |provider|
    # some complex logic here using provider
  end

我喜欢它超过:

provider = product.provider
some_variable = 
  if provider
    # ...
  end

或者在任何地方使用product.provider。不过是口味的问题。

相关问题