简体   繁体   English

在Rails / Ruby中检查对象是否存在的正确方法是什么?

[英]What is the proper way to check for existence of objects in Rails / Ruby?

I have a lot of models and relations. 我有很多模特和关系。 Due to this fact, there is lot of calls in views/controllers, which look like this: 由于这个事实,在视图/控制器中有很多调用,如下所示:

 @object.something.with_something.value 

Some part of the chain can end up being nil, which is perfectly ok. 链的某些部分最终可能是零,这是完全可以的。 What is the proper/clean/fast way to check for the existence of the terminal object? 检查终端对象是否存在的正确/清洁/快速方法是什么?

Is calling something like: 是这样的:

 @object.something.with_something.value if defined? @object.something.with_something.value 

Considered ok? 认为好吗?

Natively, you'd need to use the && operator (not defined? ), but this can get very verbose, very quickly. 在本地,您需要使用&&运算符( defined? ),但这可能非常冗长,非常快。

So instead of doing this: 所以不要这样做:

(@object && @object.something && @object.something.with_something &&
  @object.something.with_something.value)

You can do this when ActiveSupport is present: 您可以在ActiveSupport存在时执行此操作:

@object.try(:something).try(:with_something).try(:value)

Or install the invocation construction kit and use its guarded evaluation tools: 或者安装调用构造工具包并使用其保护的评估工具:

Ick::Maybe.belongs_to YourClass
maybe(@object) { |obj| obj.something.with_something.value }

It's best to arrange the rest of your code in order to see this problem for at most the last object in a chain. 最好安排其余代码,以便最多查看链中最后一个对象的问题。

defined? won't do what you want. 不会做你想要的。 Something can be defined? 有什么东西可以defined? and nil at the same time. 并且同时nil

When the problem is restricted to the last attribute in a chain of references: 当问题仅限于引用链中的最后一个属性时:

@object.something.with_something.value if @object.something.with_something

I might take advantage of the facts that: 我可能会利用以下事实:

nil.to_a => []
nil.to_s => ''
nil.to_f => 0.0
nil.to_i => 0

So, if you know that something is either nil or an Array , often you can write better code without any conditionals at all by writing something like: 所以,如果你知道某些东西是nil或者是一个Array ,你通常可以通过编写类似的东西来编写更好的代码而不需要任何条件

something.to_a.each do |e|
  . . .

what.you.are.doing is sometimes called a "Train wreck". what.you.are.doing有时被称为“火车残骸”。 It's also described as a violation of the Law of Demeter. 它也被描述为违反了得墨忒耳法。

That being said, I think there's something called "andand" that can help with what you're doing. 话虽如此,我认为有一种叫做“andand”的东西可以帮助你正在做的事情。

Another option is to use the Null Object pattern to ensure that none of those objects is ever nil. 另一种选择是使用Null Object模式来确保这些对象都不是零。 Arguably, if your code is going to chain access in that way, then something should always be defined. 可以说,如果你的代码以这种方式进行链接访问,那么应该总是定义一些东西

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM