在列中将列types更改为更长的string

在第一次迁移时,我声明了一个字段content是stringActiverecord根据注释gem使它成为string(255)。

在我将应用程序推送到使用postgres的heroku之后,如果我在内容的表单中input一个超过255的string,我得到错误

 PGError: ERROR: value too long for type character varying(255) 

问题是我需要那个内容来包含一个非常长的string(自由文本,可能是成千上万的字符)

  1. 什么variables(是string不适合这个)会接受?
  2. 如何创build一个迁移来replace该列的types

谢谢

如果你想要一个没有长度限制的string,你应该使用Rails的text 。 像这样的迁移:

 def up change_column :your_table, :your_column, :text end def down # This might cause trouble if you have strings longer # than 255 characters. change_column :your_table, :your_column, :string end 

应该把事情弄清楚。 您可能需要:null => false或者其他一些选项。

当你使用没有显式限制的string列时,Rails会添加一个隐含的:limit => 255 。 但是如果你使用text ,你会得到任何长度的数据库支持的stringtypes。 PostgreSQL允许你使用一个没有长度的varchar列,但是大多数数据库使用一个单独的types,而Rails不知道没有长度的varchar 。 您必须在Rails中使用text才能在PostgreSQL中获取text列 。 PostgreSQL在一个types的text列和一个varchartypes(但是varchar(n)不同)之间没有区别。 另外,如果你在PostgreSQL上部署,根本就没有理由使用:string (AKA varchar ),除了varchar(n)的额外长度限制外,数据库在内部对待textvarchar(n) 。 如果在列大小上有一个外部约束(例如表单897 / B上的字段432长度为23个字符的政府表单),则只应使用varchar(n) (又名:string )。

另外,如果您在任何地方使用string列,则应始终指定:limit作为提醒您自己有一个限制,并且您应该在模型中进行validation以确保不超过限制。 如果超出限制,PostgreSQL会发出抱怨并引发exception,MySQL会静静地截断string或​​者抱怨(取决于服务器configuration),SQLite会让它按原样传递,其他数据库会做其他事情(可能是抱怨) 。

另外,您还应该在同一个数据库(通常是Heroku的PostgreSQL)上进行开发,testing和部署,甚至应该使用相同版本的数据库服务器。 数据库之间还有其他的不同之处(比如GROUP BY的行为),ActiveRecord不会让你失望。 你可能已经这样做了,但是我想我会提到它。

虽然接受的答案非常好,但我想在这里添加一个答案,希望能更好地处理原始海报问题第2部分,对于像我这样的非专家。

  1. 如何创build一个迁移来replace该列的types

产生脚手架迁移

您可以通过input您的控制台来生成一个迁移来保存您的更改(只需将表名replace为表,列名为列)

 rails generate migrate change_table_column 

这将在您的Rails应用程序/ db / migrate /文件夹中生成骨架迁移。 此迁移是您的迁移代码的占位符。

例如,我想要创build一个迁移,将一个列的types从string更改为text ,名为TodoItems:

 class ChangeTodoItemsDescription < ActiveRecord::Migration def change # enter code here change_column :todo_items, :description, :text end end 

运行您的迁移

一旦你input了代码来改变列只是运行:

 rake db:migrate 

应用您的迁移。 如果发生错误,您可以随时使用以下命令恢复更改:

 rake db:rollack 

上下方法

接受的答案引用UpDown方法,而不是较新的Change方法。 由于rails 3.2 旧式的 Up和Down方法比较新的Change方法有一些优点。 '上下'避免ActiveRecord::IrreversibleMigration exception 。 自Rails 4发布以来,您可以使用reversible来避免此错误:

 class ChangeProductsPrice < ActiveRecord::Migration def change reversible do |dir| change_table :products do |t| dir.up { t.change :price, :string } dir.down { t.change :price, :integer } end end end end 

享受Rails 🙂