Rails 3.1: can't write to column in same migration that adds it

半城伤御伤魂 提交于 2019-12-02 23:50:29

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!