Rails 3.1:无法在添加它的同一个迁移中写入列

我有一个可以正常运行的add_column迁移。 但是,在运行它并启动控制台后,我会发现first_name和last_name列完全为空。 我试过用save! 相反,它具有相同的效果 – 没有报告错误。 这是原始的:

 class UserAddFirstNameAndLastName < ActiveRecord::Migration def change # add column first name, last name string add_column :users, :first_name, :string add_column :users, :last_name, :string User.all.each do |u| u.first_name = 'first name' u.last_name = 'last name' u.save end end end 

我还认为这可能是一些类加载问题,所以我插入了User行来强制用户类在循环之前重新加载。 没有骰子。

当我将其拆分为两次迁移时,实现了期望的效果。 有人对此有解释吗? 我发誓我甚至在过去迁移的同一个项目中做过这个。

其他说明:设计用户引擎,在运行迁移之前将新列添加到User类中的attr_accessible

在迁移运行之前,您正在某处加载Users类,因此User对其自身结构有点困惑。 解决方案是在添加列后调用reset_column_information

重置有关列的所有缓存信息,这将导致它们在下一个请求时重新加载。

此方法最常见的使用模式可能是迁移,在创建表后,您希望使用某些默认值填充它

“ 迁移指南”中的“ 迁移中的使用模型”部分也值得一看。

尝试回滚并使用如下迁移:

 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_columnsome_column NULL值,第三个也有效。

我猜你的应用程序初始化(可能来自Devise)导致用户及其架构被加载,然后你添加一列。 但是,显然,用户只是部分知道新列,因为u.first_name调用有效但在User内部缓存了某些内容以防止将属性写入数据库。