在现有的 Rails 列中添加: default = > true to boolean

我在 SO 上看到了一些关于向现有列添加默认布尔值的问题(即 这个)。所以我尝试了 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

有人能告诉我,我哪里做错了吗?

144018 次浏览

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。

作为公认答案的一个变体,你也可以在你的迁移中使用 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

我不确定这是什么时候写的,但是当前要从迁移中的列中添加或删除默认值,您可以使用以下方法:

change_column_null :products, :name, false

铁路5:

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

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

轨道4.2:

change_column_default :products, :approved, false

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

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

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

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

要进行回滚,您可以执行任意多个步骤:

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

还有,根据医生的说法:

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

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

所以没有现成的轨道发电机。正如上面的答案所指定的那样,您必须使用 change_column_default方法手动填充迁移文件。

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

如果你不想从 Rails 控制台创建另一个迁移文件(针对一个小的、最近的更改) :

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

然后退出并重新进入 Rails 控制台,这样 DB-Changes 将生效。

Profile.new()

您应该看到“ show _ tribute”default-value 为 true。

对于现有的记录,如果您想保留现有的“假”设置,并且只更新“ nil”值到新的默认值:

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

更新创建这个表的迁移,这样 DB 的任何未来构建都将从一开始就获得正确的结果。还可以在 DB 的任何已部署实例上运行相同的进程。

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