我在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
有人能告诉我这里的错误吗?
答案 0 :(得分:298)
change_column
是ActiveRecord::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
答案 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值。