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

时间:2012-07-07 18:32:54

标签: ruby-on-rails arrays ruby-on-rails-3.2

我是Ruby和Rails框架的新手。我的背景主要是Java。无论如何,我面临一个奇怪的情况。我在我的一个模型中有一个返回相关模型的方法。该协会如下。 a_many Bs,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。我还在挠挠脑袋。我还没有找到类似的帖子。

3 个答案:

答案 0 :(得分:1)

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

检查documentation。 但无论如何,你不应该使用这样的关系。使用has_manybelongs_to表示模型之间的关系。像这样:

class ModelA < ActiveRecord::Base
  has_many :ModelB
end 

class ModelB < ActiveRecord::Base
  belongs_to :ModelA
end 

答案 1 :(得分:1)

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

示例:

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

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

我认为我最终要做的是创建一个使用.try方法的辅助方法。这样,我不会在我的观点中调用.try

答案 2 :(得分:0)

为什么不使用它?

def get_bs
  ModelB.find_all_by_a_id(id)
end