添加:默认=>在现有Rails列中为true

时间:2011-12-24 22:15:28

标签: ruby-on-rails-3 migration

我在SO上看到了一些关于向现有列添加默认布尔值的问题(即this one)。所以我尝试了change_column建议,但我不能做得对。

我试过了:

$ change_column :profiles, :show_attribute, :boolean, :default => true

返回-bash: change_column: command not found

然后我跑了:

$ rails g change_column :profiles, :show_attribute, :boolean, :default => true

...和

$ rails change_column :profiles, :show_attribute, :boolean, :default => true

然后运行rake db:migrate,但:show_attribute的值仍为nil。在我上面提到的问题中,它在PostgreSQL中说你需要手动更新它。由于我正在使用PostgreSQL,因此我在create_profiles迁移中添加了以下内容:

t.boolean :show_attribute, :default => true

有人能告诉我这里的错误吗?

7 个答案:

答案 0 :(得分:298)

change_columnActiveRecord::Migration的方法,所以你不能在控制台中调用它。

如果要为此列添加默认值,请创建新的迁移:

rails g migration add_default_value_to_show_attribute

然后在创建的迁移中:

# That's the more generic way to change a column
def up
  change_column :profiles, :show_attribute, :boolean, default: true
end

def down
  change_column :profiles, :show_attribute, :boolean, default: nil
end

或更具体的选项:

def up
    change_column_default :profiles, :show_attribute, true
end

def down
    change_column_default :profiles, :show_attribute, nil
end

然后运行rake db:migrate

它不会改变已创建的记录。要做到这一点,您必须创建rake task或者只需进入rails console并更新所有记录。

t.boolean :show_attribute, :default => true添加到create_profiles迁移时,如果它没有执行任何操作,则是正常的。仅执行尚未运行的迁移。如果您从一个新数据库开始,那么它会将默认值设置为true。

答案 1 :(得分:93)

作为已接受答案的变体,您还可以在迁移中使用change_column_default方法:

def up
  change_column_default :profiles, :show_attribute, true
end

def down
  change_column_default :profiles, :show_attribute, nil
end

Rails API-docs

答案 2 :(得分:30)

我不确定何时写入,但目前要在迁移中添加或删除列中的默认值,您可以使用以下内容:

change_column_null :products, :name, false

Rails 5:

change_column_default :products, :approved, from: true, to: false

http://edgeguides.rubyonrails.org/active_record_migrations.html#changing-columns

Rails 4.2:

change_column_default :products, :approved, false

http://guides.rubyonrails.org/v4.2/active_record_migrations.html#changing-columns

这是一种避免查看列规范的迁移或模式的简洁方法。

答案 3 :(得分:1)

如果您刚刚进行了迁移,则可以回滚,然后再次进行迁移。

要回滚,您可以根据需要执行许多步骤:

rake db:rollback STEP=1

或者,如果您使用的是Rails 5.2或更高版本:

rails db:rollback STEP=1

然后,您可以再次进行迁移:

def change
  add_column :profiles, :show_attribute, :boolean, default: true
end

别忘了rake db:migrate,如果您正在使用heroku heroku run rake db:migrate

答案 4 :(得分:0)

change_column :things, :price_1, :integer, default: 123, null: false

似乎是将默认值添加到尚未有null: false的现有列的​​最佳方式。

否则:

change_column :things, :price_1, :integer, default: 123

我对此做了一些研究:

https://gist.github.com/Dorian/417b9a0e1a4e09a558c39345d50c8c3b

答案 5 :(得分:0)

此外,根据文档:

  

不能通过命令行指定默认值

https://guides.rubyonrails.org/active_record_migrations.html

因此,没有现成的rails生成器。如以上答案所指定,您必须使用change_column_default方法手动填充迁移文件。

您可以创建自己的生成器:https://guides.rubyonrails.org/generators.html

答案 6 :(得分:0)

如果您不希望为Rails控制台中的最近的小更改创建另一个迁移文件:

ActiveRecord::Migration.change_column :profiles, :show_attribute, :boolean, :default => true

然后退出并重新进入rails控制台,因此DB-Changes将生效。然后,如果您这样做...

Profile.new()

您应该看到“ show_attribute”默认值为true。

对于现有记录,如果要保留现有的“ false”设置,而仅将“ nil”值更新为新的默认值:

Profile.all.each{|profile| profile.update_attributes(:show_attribute => (profile.show_attribute == nil ? true : false))  }

更新创建此表的迁移,因此任何将来的数据库构建都将从一开始就正确使用它。还可以在数据库的任何已部署实例上运行相同的过程。

如果使用“新数据库迁移”方法,则可以更新该迁移中的现有nil值。