Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a Person model & an Item model. A person has many items, and an item belongs to a person.

In this code, I need to delete the existing items for a person, and create new ones from a parameter (which is an array of hashes). Then, I need to update one of the item's fields, based on one of its other fields.

@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

On the x.item_amount = "5" & x.item_amount = "10" lines I get this error:

RuntimeError in PersonsController#submit_items
can't modify frozen hash 

How can I fix this? Thanks for reading.

like image 331
ben Avatar asked Dec 19 '10 05:12

ben


1 Answers

I would suspect

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

returns a frozen hash which you then use to create objects

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

And since its frozen you can't modify it.

You could

A Make a deep copy of the JSON object

or

B Reload the model instance which should reinstantiate the object making the fields unfrozen.

Option A is the "better" solution but difficult because the only way I know of deep copying is serializing and deserializing and object in place and assigning the return value.

like image 110
EnabrenTane Avatar answered Oct 26 '22 06:10

EnabrenTane