通过迁移向列添加默认值

Jon*_*Jon 259 ruby migration ruby-on-rails

如何向通过迁移已存在的列添加默认值?

我可以找到的所有文档都向您展示了如果列尚不存在但是在这种情况下它是如何实现的.

Mau*_*res 336

这是你应该怎么做的:

change_column :users, :admin, :boolean, :default => false
Run Code Online (Sandbox Code Playgroud)

但是某些数据库(如PostgreSQL)不会更新以前创建的行的字段,因此请确保在迁移时手动更新字段.

  • 如果需要可逆迁移,请将其放在`up`块而不是`change`块中.你可以将`down`块留空.它不会将表还原为原始条件,但可以回滚迁移. (14认同)
  • 我在PostgreSQL上尝试过,它更新了以前创建的字段. (5认同)
  • @AboozarRajabi 我刚刚在 PostgreSQL 上尝试过,它**没有**更新以前创建的字段。 (5认同)
  • 在PostgreSQL上,是的,我不知道其他数据库会发生什么. (2认同)

Gaz*_*zza 184

change_column_default :employees, :foreign, false
Run Code Online (Sandbox Code Playgroud)

  • 这应该完全是公认的答案. (13认同)
  • **在此提交中,在Rails 5+中添加了使用`from`和`to`:https://github.com/rails/rails/pull/20018/files** (3认同)
  • 除此之外,你需要指定一个`from:`和`to:`如果你想要它是可逆的:) (2认同)

csi*_*csi 108

对于Rails 4+,请使用change_column_default

def change
  change_column_default :table, :column, value
end
Run Code Online (Sandbox Code Playgroud)

  • 这种迁移具有奇怪的行为。在您的示例中,这是不可逆的。http://edgeguides.rubyonrails.org/active_record_migrations.html建议以这种方式使用它:`change_column_default:products,:approved,从:true,到:false`-但它也不起作用。 (2认同)

bfc*_*der 46

使用def change意味着您应该编写可逆的迁移.并且change_column不可逆转.你可以上去,但你不能下去,因为change_column是不可逆转的.

相反,虽然它可能是一些额外的行,你应该使用def updef down

因此,如果您的列没有默认值,那么您应该这样做以添加默认值.

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: nil
end
Run Code Online (Sandbox Code Playgroud)

或者,如果要更改现有列的默认值.

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: true
end
Run Code Online (Sandbox Code Playgroud)


Pra*_*rge 34

**Rails 4.X +**

从Rails 4开始,您无法生成迁移以将列添加到具有默认值的表中 .以下步骤将新列添加到现有表,其默认值为true或false.

1.从命令行运行迁移以添加新列

$ rails generate migration add_columnname_to_tablename columnname:boolean
Run Code Online (Sandbox Code Playgroud)

上面的命令将在表中添加一个新列.

2.通过编辑创建的新迁移文件,将新列值设置为TRUE/FALSE.

class AddColumnnameToTablename < ActiveRecord::Migration
  def change
    add_column :table_name, :column_name, :boolean, default: false
  end
end
Run Code Online (Sandbox Code Playgroud)

**3.要对应用程序数据库表进行更改,请在终端**中运行以下命令

$ rake db:migrate
Run Code Online (Sandbox Code Playgroud)

  • 有人知道它是否已合并到Rails 5中吗? (2认同)

小智 8

执行:

rails generate migration add_column_to_table column:boolean
Run Code Online (Sandbox Code Playgroud)

它将生成此迁移:

class AddColumnToTable < ActiveRecord::Migration
  def change
    add_column :table, :column, :boolean
  end
end
Run Code Online (Sandbox Code Playgroud)

设置默认值add:default => 1

add_column:table,:column,:boolean,:default => 1

跑:

rake db:migrate

  • 现在默认值1不是一个布尔值;)此外,这个示例*添加*一个新列,而不是更改现有列,这是OP想要实现的 (2认同)

roo*_*ler -62

这是你可以做的:

class Profile < ActiveRecord::Base
  before_save :set_default_val

  def set_default_val
    self.send_updates = 'val' unless self.send_updates
  end
end
Run Code Online (Sandbox Code Playgroud)

编辑:......但显然这是一个菜鸟错误!

  • 多么糟糕的建议 (9认同)
  • 哎呀,你因为在模型级别而不是数据库级别做某事而感到非常热衷。-38是一个传奇的分数。 (9认同)
  • 多么菜鸟的错误...;-) (3认同)