Ответ 1
Вы загружаете класс Users где-то до начала миграции, поэтому User
немного запутался в своей структуре. Решение заключается в вызове reset_column_information
после добавления столбца:
Сбрасывает всю кешированную информацию о столбцах, что приведет к их перезагрузке при следующем запросе.
Наиболее распространенный шаблон использования для этого метода, вероятно, связан с переносом, когда сразу после создания таблицы вы хотите заполнить его некоторыми значениями по умолчанию
Использование моделей в ваших миграциях в разделе Migrations Guide также может быть интересным.
Попробуйте откат и используя миграцию следующим образом:
def change
# add column first name, last name string
add_column :users, :first_name, :string
add_column :users, :last_name, :string
User.reset_column_information
User.all.each do |u|
u.first_name = 'first name'
u.last_name = 'last name'
u.save
end
end
Я проверил это с тремя миграциями:
# 1: Don't touch Model before the new columns.
def change
add_column :models, :some_column, :string
Model.all.each { |m| m.some_column = 'pancakes'; m.save }
end
# 2: Pull in Model before adding the new columns.
def change
puts Model.all.count
add_column :models, :some_column, :string
Model.all.each { |m| m.some_column = 'pancakes'; m.save }
end
# 3: Pull in Model before adding the new columns but use reset_column_information
def change
puts Model.all.count
add_column :models, :some_column, :string
Model.reset_column_information
Model.all.each { |m| m.some_column = 'pancakes'; m.save }
end
Первый работает просто отлично, второй добавляет some_column
, но оставляет его с NULL-значениями, третий работает.
Я бы предположил, что что-то в вашей инициализации приложения (возможно, из Devise) вызывает загрузку User и его схемы, после чего вы добавляете столбец. Но, по-видимому, пользователь только частично знает о новом столбце, поскольку работает вызов u.first_name
, но что-то кэшируется внутри пользователя, чтобы предотвратить запись атрибута в базу данных.