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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With