将键附加到每个循环中的哈希

时间:2016-05-17 22:18:54

标签: ruby-on-rails arrays ruby hash

我正在浏览一个rails Hash教程并且陷入了如何在循环中操纵哈希的问题。我有一个名为products的哈希:

products = Product.where(category: 'electronics', price: 10000).pluck_to_hash(:id)
# => [{:id=>23}, {:id=>12}, {:id=>108}]

我的目标是像这样迭代它:

products.each do |p|
  @store = Store.where(product: p[:id], country: gb).pluck_to_hash(:store_code, :manager_name)
end

并将所有6个商店结果存储在@store实例变量中,以便我可以将其传递给view。

使用=最终只能使用一个 商店,而不是我试图得到的所有6家商店。 <<仅适用于数组。

我也试过

@store.merge!(Store.where(product: p[:id], country: gb).pluck_to_hash(:store_code, :manager_name))

得到了:

  

未定义的方法`合并!&#39;为零:NilClass

然后我在循环之前声明了一个空哈希:

@store = {} 

这给了:

  

没有将Array隐式转换为Hash

有关如何在@store变量中迭代存储这些键的任何指导将非常感激。

请注意,这个问题不是关于模型关联;它特定于哈希操纵。

1 个答案:

答案 0 :(得分:2)

这就是它不起作用的原因:

在循环的每次迭代中,您将变量@store替换为另一个ActiveRecord::ProxyCollection

products.each do |p|
  @store = Store.where(product: p[:id], country: gb).pluck_to_hash(:store_code, :manager_name)
end

虽然你可以这样做:

products.each do |p|
  @store[p[:id]] = Store.where(product: p[:id], country: gb).pluck_to_hash(:store_code, :manager_name)
end

然而,这只是从一开始就解决问题的错误方法。

哈希用于存储键值数据,其中值对应于已知键。 Ruby不像PHP那样完全混合了数组和字典,如“对象”(关联数组)。

数组就像堆栈一样,顺序很重要,散列是关键值。你想要的不是哈希。

相反,你会这样解决它:

products = Product.where(category: 'electronics', price: 10000).pluck(:id)
# this gives us an array of ids
@stores = Store.where(product: products, country: gb)

但是你最好在这里设置正确的关系,并在连接表上使用.joins条件。

@stores = Store.joins(:product)
               .where(product: { category: 'electronics', price: 10000 }, country: gb)

这样效率更高。