Ruby:通过索引和迭代器访问数组对象



我对Ruby和Rails框架还很陌生。我的背景主要是Java。不管怎样,我面临着一个奇怪的情况。我的一个模型中有一个方法,它返回关联的模型。关联如下。A有多个B,B属于A(即一对多)

class ModelA < ActiveRecord::Base
  has_many :model_bs
  def get_bs
    ModelB.where(:a_id => id)
  end
end 
class ModelB < ActiveRecord::Base
  belongs_to :model_a
end

在我看来,如果我试图访问结果集中的记录(模型),我就可以毫无问题地调用它的属性(图A)。生活是美好的。

图A:

<% bs = a.get_bs %>
<% bs.each do |b| %> 
  <%= b.some_prop %> 
<% end %>

但是,如果我试图通过索引访问模型,我会得到一个错误,说我不能在nil对象上调用方法(图B&C)。

图B:

<% bs = a.get_bs %>
<%= bs[0].some_prop) %>

甚至。。

图C:

<% bs = a.get_bs %>
<%= bs[0].first %>

不起作用。我知道这是用户错误(我)。我已经查看了访问集合中对象的文档(在本例中,我认为它是一个Ruby数组)。我也在这里搜索过StackOverflow。我仍然在挠头。我还没有找到类似的线索。

您错了,它不是Array,而是ActiveRecord::Relation类。如果你真的需要,你可以用.to_a把它转换成一个数组。我已经检查过了,你可以使用[]运算符按索引访问项:ModelA.where("created_at = created_at")[0].name,所以我认为问题出在其他地方,可能是在你的情况下。

查看文档。但无论如何,你不应该这样利用这种关系。使用has_manybelongs_to来表示模型之间的关系。像这样:

class ModelA < ActiveRecord::Base
  has_many :ModelB
end 
class ModelB < ActiveRecord::Base
  belongs_to :ModelA
end 

我找到了一个解决方案。它不漂亮,但现在就到期了。在LinkedIn上的一些人的帮助下,我发现在尝试访问属性时,在我的模型上使用.try方法,我可以在没有空指针异常的情况下检索值。

示例:

<% bs = a.get_bs.to_a%>
<%= bs[0].try(:some_attr) %>

我不清楚为什么我需要使用.try方法。我的意思是,我知道这个方法的作用。这是一种方便的方法,用于检查nil值,并允许在不引发异常的情况下呈现页面。但很明显,我的模型不是空的,它有数据。那么,为什么我只能使用.try方法访问它的属性呢?老实说,我认为这可能是Rails中的一个错误。

我想我最终要做的是创建一个使用.try方法的helper方法。这样,我就不会因为我的观点而打电话给.try

为什么不使用这个?

def get_bs
  ModelB.find_all_by_a_id(id)
end

最新更新