Ruby-on-rails 在 rails 中将列类型更改为更长的字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8694273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing a column type to longer strings in rails
提问by Nick Ginanto
At the first migration, I declared on a column contentto be string
Activerecord made it to be string(255) according to annotate gem.
在第一次迁移时,我在一个列content上声明为 string Activerecord 根据 annotate gem 将其设为 string(255)。
After I push the app to heroku, which uses postgres, if I enter in the form in content a string longer than 255 I get the error
在我将应用程序推送到使用 postgres 的 heroku 之后,如果我在 content 中的表单中输入一个长度超过 255 的字符串,我会收到错误消息
PGError: ERROR: value too long for type character varying(255)
Problem is I need that content to contain a string that is extremely long perhaps (free text, could be thousands of chars)
问题是我需要该内容包含一个可能非常长的字符串(自由文本,可能是数千个字符)
- What variable (is string is not appropriate for this) would pg accept?
- How do I create a migration to replace the type of that column
- pg 会接受什么变量(字符串不适合于此)?
- 如何创建迁移以替换该列的类型
thanks
谢谢
回答by mu is too short
You should use textwith Rails if you want a string with no length limit. A migration like this:
text如果你想要一个没有长度限制的字符串,你应该使用Rails。像这样的迁移:
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
should sort things out. You might want :null => falseor some other options on the end of that too.
应该整理一下。最后,您可能还想要:null => false或其他一些选项。
When you use a stringcolumn without an explicit limit, Rails will add an implicit :limit => 255. But if you use text, you'll get whatever arbitrary length string type the database supports. PostgreSQL allows you to use a varcharcolumn without a length but most databases use a separate type for that and Rails doesn't know about varcharwithout a length. You have to use textin Rails to get a textcolumnin PostgreSQL. There's no difference in PostgreSQL between a column of type textand one of type varchar(but varchar(n)isdifferent). Furthermore, if you're deploying on top of PostgreSQL, there's no reason to use :string(AKA varchar) at all, the database treats textand varchar(n)the same internally except for the extra length constraints for varchar(n); you should only use varchar(n)(AKA :string) if you have an external constraint (such as a government form that says that field 432 on form 897/B will be 23 characters long) on the column size.
当您使用string没有明确限制的列时,Rails 会添加一个隐式的:limit => 255. 但是,如果您使用text,您将获得数据库支持的任意长度的字符串类型。PostgreSQL 允许您使用varchar没有长度的列,但大多数数据库为此使用单独的类型,而 Rails 不知道varchar没有长度的列。您必须text在 Rails 中使用才能在 PostgreSQL 中获取一text列。有类型的列之间PostgreSQL中没有差异text和类型的一个varchar(但varchar(n)是不同)。此外,如果您在 PostgreSQL 之上部署,则根本没有理由使用:string(AKA varchar),数据库会处理text并varchar(n)除了额外的长度限制外,内部相同varchar(n);如果您对列大小有外部约束(例如,政府表格表明表格 897/B 上的字段 432 的长度为 23 个字符),则您应该仅使用varchar(n)(AKA :string)。
As an aside, if you are using a stringcolumn anywhere, you should always specify the :limitas a reminder to yourself that there is a limit and you should have a validation in the model to ensure that the limit is not exceeded. If you exceed the limit, PostgreSQL will complain and raise an exception, MySQL will quietly truncate the string or complain (depending on the server configuration), SQLite will let it pass as-is, and other databases will do something else (probably complain).
顺便说一句,如果您在string任何地方使用列,您应该始终指定:limit作为提醒自己存在限制并且您应该在模型中进行验证以确保不超过限制。如果超过限制,PostgreSQL 会抱怨并引发异常,MySQL 会悄悄地截断字符串或抱怨(取决于服务器配置),SQLite 会让它按原样通过,其他数据库会做其他事情(可能会抱怨) .
Also, you should also be developing, testing, and deploying on top of the same database (which will usually be PostgreSQL at Heroku), you should even use the same versions of the database server. There are other differences between databases (such as the behavior of GROUP BY) that ActiveRecord won't insulate you from. You might be doing this already but I thought I'd mention it anyway.
此外,您还应该在同一个数据库(通常是 Heroku 的 PostgreSQL)之上开发、测试和部署,您甚至应该使用相同版本的数据库服务器。ActiveRecord 不会将您与数据库之间的其他差异(例如 GROUP BY 的行为)隔离开来。你可能已经这样做了,但我想我还是会提到它。
回答by Tony Cronin
While the accepted answer is excellent, I wanted to add an answer here that hopefully better deals with the original posters question part 2, for non experts like myself.
虽然接受的答案很好,但我想在这里添加一个答案,希望能更好地处理原始海报问题第 2 部分,对于像我这样的非专家。
- How do I create a migration to replace the type of that column
- 如何创建迁移以替换该列的类型
generating scaffold migration
产生脚手架迁移
You can generate a migration to hold your change by typing in your console (just replace the tablefor your tables name, and columnfor you column name)
您可以通过在控制台中键入来生成迁移以保存更改(只需替换table表名和column列名)
rails generate migration change_table_column
This will generate skeleton migration inside you Rails application /db/migrate/ folder. This migration is a placeholder for your migration code.
这将在您的 Rails 应用程序 /db/migrate/ 文件夹中生成骨架迁移。此迁移是您的迁移代码的占位符。
For example I want to create a migration to change the type of a column from stringto text, in a table called TodoItems:
例如,我想创建一个迁移从改变一个列的类型string来text,在表中称为TodoItems:
class ChangeTodoItemsDescription < ActiveRecord::Migration
def change
# enter code here
change_column :todo_items, :description, :text
end
end
Running your migration
运行迁移
Once you've entered the code to change the column just run:
输入代码以更改列后,只需运行:
rake db:migrate
To apply your migration. If you make an error you can always revert the change with:
应用您的迁移。如果您犯了错误,您始终可以通过以下方式恢复更改:
rake db:rollack
Up and Down methods
上下方法
The accepted answer references Upand Downmethods, instead of the newer Changemethod. Since rails 3.2old styleUp and Down Methods presented a few advantages over the newer Change method. 'Up and Down' avoid ActiveRecord::IrreversibleMigration exception. Since the release of Rails 4you can use reversibleto avoid this error:
接受的答案参考Up和Down方法,而不是较新的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
Enjoy Rails :)
享受 Rails :)

