为什么在 ActiveRecord 迁移中为现有列设置默认值不会扩展到生产中的现有关联?

1 ruby activerecord ruby-on-rails rails-activerecord

如果我通过 ActiveRecord 迁移向现有列添加默认值,则在将更改部署到生产时,现有关联不会受到影响。

我可以进入 Rails 生产控制台并迭代每条记录,并将每条记录的新列上的值设置为 false,但这很乏味并且不能很好地扩展。

class AddDefaultValuesToAFewColumns < ActiveRecord::Migration[5.2]
  def change
    change_column :downloads, :is_deleted, :boolean, :default => false
  end
end
Run Code Online (Sandbox Code Playgroud)
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

Run Code Online (Sandbox Code Playgroud)

当从 Rails 控制台查询返回 is_deleted 时,预期结果是关联false,而不是返回nil。为什么会这样?有哪些替代解决方案?

ari*_*uod 5

这就是它的工作原理。当您更改列默认值时,您是在为新记录配置默认值,而不是为现有记录配置默认值。如果您想更新现有值,请在该行之后false执行类似的操作:Download.where(is_deleted: nil).update_all(is_deleted: false)change_column

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
Run Code Online (Sandbox Code Playgroud)