在迁移运行之前,您正在某处加载 Users 类User
对它自己的结构有点困惑。解决办法是调用reset_column_information http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-reset_column_information添加您的列后:
重置有关列的所有缓存信息,这将导致它们在下一个请求时重新加载。
此方法最常见的使用模式可能是在迁移中,当创建表后您想用一些默认值填充它时
The 在迁移中使用模型 http://guides.rubyonrails.org/migrations.html#using-models-in-your-migrations的部分迁移指南 http://guides.rubyonrails.org/migrations.html也许也值得一看。
尝试回滚并使用如下迁移:
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)导致加载用户及其架构,然后您添加一列。但是,显然,用户只部分了解新专栏u.first_name
调用有效,但在 User 内部缓存了某些内容,以防止将属性写入数据库。