Я бы заподозрил
ActiveSupport::JSON.decode(params["person_items"])
возвращает замороженный хеш, который вы затем используете для создания объектов
@person.person_items.create(pi) if pi.is_a?(Hash)
А поскольку он заморожен, его нельзя изменить.
Вы могли бы
А
Сделайте глубокую копию объекта JSON
или
B
Перезагрузите экземпляр модели, который должен восстановить объект, делая поля незамерзшими.
Вариант A является «лучшим» решением, но трудным, потому что я знаю только один способ глубокого копирования - сериализацию и десериализацию, создание объекта и назначение возвращаемого значения.