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

时间:2012-09-27 01:50:18

标签: ruby-on-rails ruby migration rails-migrations

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

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

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

change_table :works do |t|
        t.string :status
           if (:complete == true)
               :value => "complete"
           else
               :value => "wip"
end
呃,这看起来不太对劲。我google了一下,发现你可以设置:默认值,但这不是我想要的。任何想法/帮助都很可爱。谢谢!

2 个答案:

答案 0 :(得分:2)

您根本不需要默认值,只需添加新列并为其赋值。这样的事情应该有效:

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的信息,请参阅Migrations Guide

您也可以直接在数据库中执行此操作,但您必须注意不同的布尔表示形式(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
})

答案 1 :(得分:0)

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