I had an add_column migration that would run fine. However, after running it and firing up a console, I would find the first_name and last_name columns completely empty. I tri
You're loading the Users class somewhere before your migration runs so User
is a little confused about its own structure. The solution is to call reset_column_information after adding your column:
Resets all the cached information about columns, which will cause them to be reloaded on the next request.
The most common usage pattern for this method is probably in a migration, when just after creating a table you want to populate it with some default values
The Using Models in Your Migrations section of the Migrations Guide might be worth a look as well.
Try rolling back and using a migration like this:
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
I checked this with three migrations like this:
# 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
The first one works just fine, the second one adds some_column
but leaves it with NULL values, the third one also works.
I'd guess that something in your application initialization (possibly from Devise) is causing User and its schema to be loaded, then you add a column. But, apparently, User only partly knows about the new column as the u.first_name
call works but something is cached inside User to prevents the attribute from being written to the database.