【问题标题】:handling nil (null) values in nested relations rails 2.3.x在嵌套关系 rails 2.3.x 中处理 nil (null) 值
【发布时间】:2011-10-12 01:42:04
【问题描述】:

我目前正在工作的项目在视图中有以下类似代码

<%= product.provider.name %>

上面的代码是获取产品的“供应商”并显示他/她的名字。但我的问题是,有时当'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。

我正在研究的是一种异常处理机制,可以处理任意数量的嵌套关系。

我想你们都知道我想要做什么......

或者这是在嵌套关系中处理 nil 值的完全错误的路径

您的想法将不胜感激(我在 rails 2.3.8 上运行)

提前致谢

干杯

同人

【问题讨论】:

    标签: ruby-on-rails ruby exception-handling null


    【解决方案1】:

    这是一个常见问题。您可能需要检查这些:

    例子:

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

    【讨论】:

    • Casper 的建议是我通常所做的,定义 _?菊花链调用并有一个优雅的失败。 +1
    【解决方案2】:

    您可以挽救所有异常:

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

    【讨论】:

    • 这会起作用,但请注意,它会有效地阻止您发现任何错误。你可以输入product.totallybogus.would.never.work rescue nil,没有人会抱怨(这可能很好,也可能不好:))。
    • @Casper,是的,你完全正确。但这是其中一种选择。 :)
    • 嗨@nash,rescue nil 效果很好,只是想知道是否有一种常用的使用方法,而不是在每一行中添加它,谢谢
    【解决方案3】:

    由于我们可以使用 #try 方法或内联处理异常,这种使用方法违反了得墨忒耳法则:每个单元应该只对其他单元有有限的了解:只有单元“与当前单位密切相关。

    视图应该得到现成的对象/变量,而不是链。所以你可以尝试在模型中使用 delegate 方法,并用助手覆盖其他方法。尽可能保持你的观点干净,从设计师的角度来看待它们。

    【讨论】:

    • 好点米哈伊洛夫。有时我们会忘记 Good Design 的基础知识,以及在语言中使用的所有闪光灯。
    【解决方案4】:

    我是这样解决问题的:

    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。不过口味问题。

    【讨论】:

    • rails core 的方法几乎一样#try
    • @mikhailov 我的项目还在1.2.6,所以我无权访问try
    • 这个方法源和你的差不多unless_nil
    • def try(method, *args, &block);发送(方法,*args,&block);结束
    • @mikhailov 不,不一样(我也可以检查 rails 源代码;))。除非顺便在 Nil 类中定义它,否则您的方法将导致异常。此外,在关联的情况下,我不需要 args 或 block,但我确实喜欢确定我展示的方式。正如我所说,这是一个品味问题。
    猜你喜欢
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多