我正在尝试使用内部数组创建哈希:
# 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'
我不明白这里有什么不对吗?
答案 0 :(得分:3)
我建议使用防御性编码,前提是它不会引入逻辑错误。类似的东西:
# 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,最好。答案 1 :(得分: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
另一种方法是创建客户,而不是重新提出错误。