为什么在 ActiveRecord 迁移中为现有列设置默认值不会扩展到生产中的现有关联?
Why does setting a default value for an existing column in an ActiveRecord Migration not extend to existing associations on production?
如果我通过 ActiveRecord 迁移将默认值添加到现有列,则在将我的更改部署到生产环境时,现有关联不会受到影响。
我可以转到 rails 生产控制台并遍历每条记录,并将每条记录的新列上的值设置为 false,但这很乏味且扩展性不好。
class AddDefaultValuesToAFewColumns < ActiveRecord::Migration[5.2]
def change
change_column :downloads, :is_deleted, :boolean, :default => false
end
end
create_table "downloads", force: :cascade do |t|
t.string "version"
t.string "comment"
t.string "contributors"
t.string "release_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "download_url"
t.boolean "is_deleted", default: false
end
当从 rails 控制台查询到 return false
is_deleted 时,预期的结果是关联,而不是 returns nil
。为什么会这样?还有哪些替代解决方案?
这就是它的工作原理。当您更改列默认值时,您是在为新记录而不是现有记录配置默认值。如果您想使用 false
更新现有值,请在 change_column
行之后执行类似 Download.where(is_deleted: nil).update_all(is_deleted: false)
的操作:
class AddDefaultValuesToAFewColumns < ActiveRecord::Migration[5.2]
def change
change_column :downloads, :is_deleted, :boolean, :default => false
Download.where(is_deleted: nil).update_all(is_deleted: false)
end
end
如果我通过 ActiveRecord 迁移将默认值添加到现有列,则在将我的更改部署到生产环境时,现有关联不会受到影响。
我可以转到 rails 生产控制台并遍历每条记录,并将每条记录的新列上的值设置为 false,但这很乏味且扩展性不好。
class AddDefaultValuesToAFewColumns < ActiveRecord::Migration[5.2]
def change
change_column :downloads, :is_deleted, :boolean, :default => false
end
end
create_table "downloads", force: :cascade do |t|
t.string "version"
t.string "comment"
t.string "contributors"
t.string "release_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "download_url"
t.boolean "is_deleted", default: false
end
当从 rails 控制台查询到 return false
is_deleted 时,预期的结果是关联,而不是 returns nil
。为什么会这样?还有哪些替代解决方案?
这就是它的工作原理。当您更改列默认值时,您是在为新记录而不是现有记录配置默认值。如果您想使用 false
更新现有值,请在 change_column
行之后执行类似 Download.where(is_deleted: nil).update_all(is_deleted: false)
的操作:
class AddDefaultValuesToAFewColumns < ActiveRecord::Migration[5.2]
def change
change_column :downloads, :is_deleted, :boolean, :default => false
Download.where(is_deleted: nil).update_all(is_deleted: false)
end
end