首页 > 解决方案 > 更新迭代器中的哈希值,所有值都将是 rails 中的最后一次迭代

问题描述

我尝试使用迭代器来更新哈希中的值,作为我创建的哈希:

@period = Date.new(2019,3,1)..Date.new(2019,3,31)

@deals = Deal.includes(:staff).where(shop_id:1, created_at:@period).group_by{|t| t.staff}

data = {}
 staff_id_container = {
  total:{item1: 0, item2: 0, item3: 0}
 }

 Staff.where(shop_id: 1).select(:id).each do |staff|
  staff_id_container[staff.id] = {item1:0, item2:0, item3:0}
 end

 @period.each do |date|
  data[date] = staff_id_container.dup
 end

并且有三种方法可以更新两层嵌套结构:

1.直接替换值

@deals.each do |staff, deals_by_staff|
  deals_by_staff.group_by{|t| t.created_at.to_date}.each do |date, selected_deals|
   data[date][staff.id] = {
    item1: select_deals.select{|deal| deal.item == "item1"}.count
    item2: select_deals.select{|deal| deal.item == "item2"}.count
    item3: select_deals.select{|deal| deal.item == "item3"}.count
   }
  end
 end

2.使用合并

@deals.each do |staff, deals_by_staff|
  deals_by_staff.group_by{|t| t.created_at.to_date}.each do |date, selected_deals|
   data[date][staff.id].merge!({
    item1: select_deals.select{|deal| deal.item == "item1"}.count
    item2: select_deals.select{|deal| deal.item == "item2"}.count
    item3: select_deals.select{|deal| deal.item == "item3"}.count
   })
  end
 end

3.使用“=”声明

@deals.each do |staff, deals_by_staff|
  deals_by_staff.group_by{|t| t.created_at.to_date}.each do |date, selected_deals|
    data[date][staff.id][:item1] = select_deals.select{|deal| deal.item == "item1"}.count
    data[date][staff.id][:item2] = select_deals.select{|deal| deal.item == "item2"}.count
    data[date][staff.id][:item3] = select_deals.select{|deal| deal.item == "item3"}.count
  end
 end

data[date][staff.id]第一种方法有效,但如果is{item1: 0,item2: 0,item3: 0, item4: 0}和 the的初始值item4将被覆盖。

第二种和第三种方式是返回错误的值,它们都让每个日期的所有值都成为最后一个日期的副本。

如上所示:

{
 2019-03-01:{
  staff_1:{item1: 0, item2: 3, item3: 1, item4: 5},
  staff_2:{item1: 1, item2: 4, item3: 2, item4: 7},
 },
 2019-03-02:{
  staff_1:{item1: 0, item2: 3, item3: 1, item4: 5},
  staff_2:{item1: 1, item2: 4, item3: 2, item4: 7},
 }
} 

如果我只是想修改data[date][staff_id]like的一个键data[date][staff_id][:item1]或添加新键data[date][staff_id],我需要使用第二或第三个方式。

第二路和第三路的问题是什么?

标签: ruby-on-railsruby

解决方案


在构建数据时尝试替换dupdeep_dup

data[date] = staff_id_container.deep_dup

https://apidock.com/rails/Hash/deep_dup


推荐阅读