在rails迁移中设置不同的默认值?

我正在尝试编写迁移,它看起来像这样:

class AddStatusToWorks < ActiveRecord::Migration def self.up change_table :works do |t| t.string :status end end def self.down change_table :works do |t| t.remove :status end end end 

事实是,我想根据已经在表中的布尔值“完成”为“状态”设置不同的默认值。 如果complete = true,则status =“complete”。 如果没有,status =“正在进行中”。 (之所以我想要一个字符串而不是保持完整的布尔值是因为我希望能够为状态提供两个以上的可能性。)任何想法如何做到这一点? 我只是像这样坚持if语句

 change_table :works do |t| t.string :status if (:complete == true) :value => "complete" else :value => "wip" end 

呃,所以看起来不太对劲。 我google了一下,发现你可以设置:默认值,但这不是我想要的。 任何想法/帮助都很可爱。 谢谢!

您根本不需要默认值,只需添加新列并为其赋值。 像这样的东西应该工作:

 def self.up change_table :works do |t| t.string :status end Works.reset_column_information Works.where(:complete => true).update_all(:status => 'complete') Works.where(:complete => [false, nil]).update_all(:status => 'wip') end 

有关reset_column_information信息,请参阅“ 迁移指南” 。

您也可以直接在数据库中执行此操作,但您必须小心不同的布尔表示forms(PostgreSQL需要't''f' ,MySQL需要10 ,SQLite需要10但Rails错误地使用't''f' ,…):

 t = connection.quote(true) connection.execute(%Q{ update works set status = case complete when #{t} then 'complete' else 'wip' end }) 

请记住,创建记录时会立即创建默认值,因此还没有默认值的字段值。 您可能希望将此类逻辑移动到您的模型中。 也许在ActiveRecord回调中,即before_validation或before_save。