3

我正在尝试创建一个内部包含数组的哈希:

# create new hash to store customers and their projects
@customers = Hash.new

# get all customers from Mite
Mite::Customer.all.each do |customer|
  @customers[customer.id] = {:name => customer.name, :projects => []}
end

# get all projects from Mite and store them in the :projects array
Mite::Project.all.each do |project|
  @customers[project.customer_id][:projects] << project # line 17
end

Mite::Project.all并且Mite::Customer.all是外部 API (mite.yo.lk) 的方法。他们工作,我取回数据,所以这不是失败。

不幸的是,我必须这样做,因为 API 没有任何方法可以通过客户 ID 过滤项目。

那是错误信息:

undefined method `[]' for nil:NilClass

app/controllers/dashboard_controller.rb:17:in `block in index'
app/controllers/dashboard_controller.rb:16:in `each'
app/controllers/dashboard_controller.rb:16:in `index'

我不明白这里有什么问题?

4

2 回答 2

3

@thorstenmüller 说的是正确的。看起来项目包含对陈旧客户的引用?

我会推荐防御性编码,只要它不会引入逻辑错误。就像是:

# get all projects from Mite and store them in the :projects array
Mite::Project.all.each do |project|
  if @customers[project.customer_id].present?
    @customers[project.customer_id] << project
  end
end

同样,我只会在您的数据库中接受陈旧客户的情况下才建议这样做。

要注意的另一件事是 project.customer_id 是一致的类型(即始终是整数或字符串):

# get all customers from Mite
Mite::Customer.all.each do |customer|
  @customers[customer.id.to_i] = {:name => customer.name, :projects => []}
end

# get all projects from Mite and store them in the :projects array
Mite::Project.all.each do |project|
  @customers[project.customer_id.to_i][:projects] << project # line 17
end

我个人已经被抓住了太多次了。

HTH 和最好的。

于 2013-01-24T13:40:34.453 回答
1

如果不定义客户是不可接受的,您可以提出更具体的错误,告诉您缺少哪个客户:

Mite::Project.all.each do |project|
  begin
    @customers[project.customer_id].fetch(:projects) << project
  rescue IndexError => error
    raise(error.class, "customer missing: #{project.customer_id}", error.backtrace)
  end
end

另一种方法是创建客户而不是重新提出错误。

于 2013-01-24T13:51:13.473 回答