首页 > 解决方案 > 实例对象被自动覆盖

问题描述

所以我有一个相当不寻常的问题。我创建了一个实例变量并为其分配了一个哈希值。然后我更新该哈希并在更新后检查旧哈希是否等于新哈希。但每次,旧对象都会更新并等同于更新的记录。我这样做是因为我需要检查哈希是否已更新。这是代码片段

编辑: old_json = @old_rules.to_json new_json = @new_rules.to_json 并比较这两个似乎得到了正确的结果。我猜它正在使用同一个对象

@old_rules = @mlo.steps[params[:step_id]]["assessment_rules"]
puts "old rules"
puts @old_rules 
#{"48771"=>{"level"=>"Easy", questions"=>"881"}}
@mlo.steps[params[:step_id]]["assessment_rules"].each do |key,value|
  if (rules_data["poolname"] == value["poolname"] && rules_data["resourcetype"] == value["resourcetype"] && rules_data["level"] == value["level"])
    updated_no_of_questions = value["questions"].to_i + rules_data["questions"].to_i 
    value["questions"] = updated_no_of_questions.to_s
    @mlo.save
  end
end

@new_rules = @mlo.steps[params[:step_id]]["assessment_rules"]
puts "updated rules"
puts "new rules"
#{"48771"=>{"level"=>"Easy", questions"=>"885"}}
if (@old_rules == @new_rules)
  #but this condition satisfies as after the update, @old_rules got updated somehow!
  #@old_rules is now #{"48771"=>{"level"=>"Easy", questions"=>"885"}}
  puts "equal"
  @mlo.steps[params[:step_id]]["assessment_rules"].merge!(hash_id.to_s => rules_data)
  @mlo.save
end

标签: ruby-on-railsrubyobject

解决方案


如前所述或暗示,您的问题是,当您分配@mlo.steps[params[:step_id]]["assessment_rules"]2 个变量时,您是在为它们分配对相同哈希的引用;因此使用 2 个变量中的 1 个进行的更改将应用​​于另一个。

假设没有复杂的对象(例如除了哈希、数组、字符串、数字等)mlo,一个简单明了的方法来确定差异并直观地看到它,是调用@mlo.to_yaml(或JSON.pretty_generate(@mlo))创建一个多行人类可读表达前后的数据,并进行比较。

有诸如 Diffy 之类的工具可以以可读的方式显示差异。


推荐阅读