Ruby检查方法链是否有效

时间:2015-03-27 22:04:11

标签: ruby-on-rails ruby chain

假设我有一个Active Record类。

如果我有:

房子,有很多人,有很多狗,有很多项圈。

我不会做模式定义,因为它们很简单。

现在我想从一个我有房屋对象的页面来遍历那所房子里的所有项圈。

所以:

for c in house.people.dogs.collars do
  puts c
end

如果家中没有人,那么当链转到undefined method时,我会收到people.dogs错误。

我可以通过两种方式解决这个问题。我可以将整个事物包含在if语句的嵌套中,一次检查一个级别,如果我首先验证了链的所有部分,则只执行上面的代码。我也可以使用beginrescue

我的问题是:

还有其他办法吗?一些方法可以让我做一些像:

for c in foo(house.people.dogs.collars) do
  puts c
end

没有其他代码。 Foo会检查链是否有效,然后执行它,否则它会默默地做什么。如果没有现成的最佳方法,我将自己创建一个函数并让它返回一个哈希或数组作为保证。

1 个答案:

答案 0 :(得分:2)

您的假设不正确。因为house.people会返回一个数组。而且你无法在该阵列上调用dogs。您必须为阵列中的每个人拨打dogs

以下情况适用于这两种情况,如果协会中有元素或者没有:

house.people.flat_map(&:dogs).flat_map(&:collars)

您可能希望使用has_many through associations清除此问题,或者在house上使用封装该逻辑的方法。

此外值得一提的是,您将遇到可怕的性能,因为链中的每个步骤都会导致对数据库的多次调用。根据数据库的大小,我会考虑使用数据库连接编写专门的范围。