Я почти обновил свое приложение RoR с v4 до v5, и для завершения процесса необходимо сделать еще кое-что.
В моем приложении RoR v4 я использовал атрибуты serialize
d в качестве хэша и массива:
class ModelOne < ApplicationRecord
serialize :attribute_one_names, Hash
end
class ModelTwo < ApplicationRecord
serialize :attribute_two_names, Array
end
Теперь мне нужно обновить записи в базе данных, чтобы они соответствовали новым требованиям RoR v5.
На основании этого ответа Я могу успешно перенести данные attribute_one_names
(Hash), выполнив следующую миграцию:
class MigrationOneFromRor4ToRor5 < ActiveRecord::Migration[5.2]
class ModelOne < ApplicationRecord
self.table_name = 'model_one'
serialize :attribute_one_names
end
def up
ModelOne.all.each do |m|
h = m.attribute_one_names.to_unsafe_h.to_h
m.attribute_one_names = h
m.save!
end
end
end
Проблема связана с данными attribute_two_names
(Array).
class MigrationTwoFromRor4ToRor5 < ActiveRecord::Migration[5.2]
class ModelTwo < ApplicationRecord
self.table_name = 'model_two'
serialize :attribute_two_names
end
def up
ModelTwo.all.each do |m|
array_of_names = []
m.attribute_two_names.each do |name|
array_of_names << name.to_unsafe_h.to_h
end
# Output 1:
puts array_of_names.inspect
# => [{"name"=>"Website1Name", "url"=>"http://www.website1.com"}, {"name"=>"Website2Name", "url"=>"http://www.website2.com"}]
puts m.attribute_two_names.inspect
# => [<ActionController::Parameters {"name"=>"Website1Name", "url"=>"http://www.website1.com"} permitted: false>, <ActionController::Parameters {"name"=>"Website2Name", "url"=>"http://www.website2.com"} permitted: false>]
m.attribute_two_names = array_of_names
# Output 2:
puts m.attribute_two_names.inspect
# => [{"name"=>"Website1Name", "url"=>"http://www.website1.com"}, {"name"=>"Website2Name", "url"=>"http://www.website2.com"}]
m.save!
# Output 3:
puts m.attribute_two_names.inspect
# => []
end
end
end
Фактически, запустив эту миграцию, значения --- []
сохраняются в базе данных независимо от существующих данных, сериализованных как массив. То есть значение --- []
сохраняется для каждой записи независимо от ранее данных, присутствующих в базе данных.
Как мне решить проблему?
Примечание
Перед запуском MigrationTwoFromRor4ToRor5 в столбце базы данных attribute_two_names
есть значения, подобные этим:
---
- !ruby/hash:ActionController::Parameters
name: Website1Name
url: http://www.website1.com
- !ruby/hash:ActionController::Parameters
name: Website2Name
url: http://www.website2.com
---
- !map:ActiveSupport::HashWithIndifferentAccess
name: Website1Name
url: http://www.website1.com
- !map:ActiveSupport::HashWithIndifferentAccess
name: Website2Name
url: http://www.website2.com