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