Arrays 使用包含数组的键遍历哈希数组

Arrays 使用包含数组的键遍历哈希数组,arrays,ruby-on-rails,data-migration,ruby-hash,Arrays,Ruby On Rails,Data Migration,Ruby Hash,我想用一个包含数组的键遍历散列数组 我解释: 我有一张存储表 我有一张产品表 我有一个store\u exluded\u product表,表中有store\u id列和product\u id列 我有一个哈希数组: array = [ { :store_id => 5, :products_ids => [1, 4, 19, 40] }, { :store_id => 13, :products_ids => [2, 20, 35] }, # ... ]

我想用一个包含数组的键遍历散列数组

我解释:

  • 我有一张
    存储
  • 我有一张
    产品
  • 我有一个
    store\u exluded\u product
    表,表中有
    store\u id
    列和
    product\u id
我有一个哈希数组:

array = [
  { :store_id => 5, :products_ids => [1, 4, 19, 40] },
  { :store_id => 13, :products_ids => [2, 20, 35] },
  # ...
]
我想用
StoreExcludedProduct.create()为我的
StoreExcludedProduct
表创建新的ActiveRecord,如下所示:

身份证件 商店标识 产品标识 1. 5. 1. 2. 5. 4. 3. 5. 19 4. 5. 40 5. 13 2. 6. 13 20 7. 13 35
一种简单的方法是迭代数组和产品ID:

array.each do |hash|
  hash[:product_ids].each do |product_id|
    StoreExcludedProduct.create(
      store_id: hash[:store_id],
      product_id: product_id
    )
  end
end
您可以将上述代码包装在一个调用中,以避免每个
create
都有单独的事务,即:

StoreExcludedProduct.transaction do
  array.each do |hash|
    # ...
  end
end
这也使您的代码以全有或全无的方式运行

另一个选项是可以一次插入多个记录。为了使用它,您必须首先为每个记录构建一个属性数组,即必须拆分产品ID。这与上面的代码非常相似:

attributes = array.flat_map do |hash|
  hash[:products_ids].map do |product_id|
    { store_id: hash[:store_id], product_id: product_id }
  end
end
#=> [
#   {:store_id=>5, :product_id=>1},
#   {:store_id=>5, :product_id=>4},
#   {:store_id=>5, :product_id=>19},
#   {:store_id=>5, :product_id=>40},
#   {:store_id=>13, :product_id=>2},
#   #...
# ]
可传递到
全部插入

StoreExcludedProduct.insert_all(attributes)

请注意,这将执行原始SQL查询,而不实例化任何模型或运行任何回调或验证。

您还可以使用导入方法在单个事务中插入数据库中的所有记录

to_be_import = []
array.each do |h|
  h[:products_ids].each do |product_id|
    to_be_import << StoreExcludedProduct.new(h[:store_id],product_id)
  end
end

StoreExcludedProduct.import(
  to_be_import,
  validate: false,
  on_duplicate_key_update: {
    conflict_target: [:id],
    columns: [:store_id, :product_id]
  }
)
to\u be\u import=[]
数组。每个do | h|
h[:产品id]。每个do |产品id|

要知道,到底是什么原因导致您在解决此问题时遇到问题?您只需使用
每个
在数组上循环,并在该循环中为产品ID循环另一个
每个
。这将有助于查看您的代码。作为经验法则:总是展示你的尝试,即使它不起作用。(这样你的反对票也会减少)好吧,我现在明白我的错误了。。那么,对于10000个产品的阵列,哪种方式的性能更好呢?@fralps a bulk insert via
insert\u all
应该快得多。只要两个都试一下(可能有100或1000个条目),您就会看到。