繁体   English   中英

为什么我得到这个'无法修改冻结哈希'错误?

[英]Why am I getting this 'can't modify frozen hash' error?

我有一个Person模型和一个Item模型。 一个人有很多项目,一个项目属于一个人。

在此代码中,我需要删除一个人的现有项目,并从参数(这是一个哈希数组)创建新的项目。 然后,我需要根据其他一个字段更新项目的一个字段。

@person = Person.find(params["id"])

@person.person_items.each do |q|
    q.destroy
end

person_items_from_param = ActiveSupport::JSON.decode(params["person_items"])

person_items_from_param.each do |pi|
    @person.person_items.create(pi) if pi.is_a?(Hash)
end

@person.person_items.each do |x|
    if x.item_type == "Type1"
        x.item_amount = "5"
    elsif x.item_type == "Type2"
        x.item_amount = "10"
    end
    x.save
end

x.item_amount = "5"x.item_amount = "10"行上,我收到此错误:

RuntimeError in PersonsController#submit_items
can't modify frozen hash 

我怎样才能解决这个问题? 谢谢阅读。

我怀疑

ActiveSupport::JSON.decode(params["person_items"])

返回一个冻结的哈希值,然后用它来创建对象

@person.person_items.create(pi) if pi.is_a?(Hash)

而且因为冻结你不能修改它。

你可以

A制作JSON对象的深层副本

要么

B重新加载模型实例,该实例应重新实例化对象,使字段解冻。

选项A是“更好”的解决方案,但很难,因为我知道深度复制的唯一方法是序列化和反序列化以及对象并分配返回值。

如果在保存元素之前使用q.destroy,那么您将收到错误。 最好先保存元素然后再使用destroy。

如果您再次从数据库中读取person_items而不是使用关联,则可以解决此问题。 该关联是陈旧的,并指向被破坏的行。

而不是@person.person_items.each do |x|

尝试PersonItem.where(:person_id=>@person.id).each do |x|

您可以在rails中包含JSON的任何对象的深层副本,所以就这样做。 请记住, clone保留冻结状态,而dup则不会。

修复错误的最简单方法can't modify frozen Arraydup此冻结数组;)

person_items_from_param = ActiveSupport::JSON.decode(params["person_items"]).dup

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM