Изменение типа столбца на более длинные строки в рельсах - PullRequest
88 голосов
/ 01 января 2012

При первой миграции я объявил в столбце content строку String. Activerecord сделал ее строкой (255) в соответствии с полем annotate.

После того, как я перенес приложение в heroku, использующее postgres, если я ввожу в форму с содержимым строку длиннее 255, я получаю сообщение об ошибке

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

Проблема в том, что мне нужно, чтобы содержимое содержало очень длинную строку (возможно, свободный текст может быть тысячchars)

  1. Какую переменную (строка не подходит для этого) будет принимать pg?
  2. Как создать миграцию для замены типа этого столбца

спасибо

Ответы [ 2 ]

208 голосов
/ 01 января 2012

Вы должны использовать 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

должна разобраться.Возможно, вы захотите :null => false или некоторые другие опции в конце этого.

Когда вы используете столбец string без явного ограничения, Rails добавит неявный :limit => 255.Но если вы используете text, вы получите произвольный тип строки, поддерживаемый базой данных.PostgreSQL позволяет использовать столбец varchar без длины, но большинство баз данных используют отдельный тип для этого, и Rails не знает о varchar без длины.Вы должны использовать text в Rails, чтобы получить text столбец в PostgreSQL.В PostgreSQL нет никакой разницы между столбцом типа text и столбцом типа varchar (но varchar(n) отличается от ).Кроме того, если вы развертываете поверх PostgreSQL, нет никакой причины использовать :string (AKA varchar) вообще, база данных обрабатывает text и varchar(n) внутренне одинаково, за исключением ограничений дополнительной длины для varchar(n);Вы должны использовать varchar(n) (AKA :string) только в том случае, если у вас есть внешнее ограничение (например, правительственная форма, в которой указано, что поле 432 в форме 897 / B будет иметь длину 23 символа) для размера столбца.

Кроме того, если вы где-либо используете столбец string, вы всегда должны указывать :limit в качестве напоминания себе о том, что существует предел, и вы должны иметь проверку в модели, чтобы убедиться, что пределне превышенЕсли вы превысите лимит, PostgreSQL будет жаловаться и выдавать исключение, MySQL будет тихо урезать строку или жаловаться (в зависимости от конфигурации сервера), SQLite позволит ей пройти как есть, а другие базы данных сделают что-то другое (возможно, будут жаловаться).

Кроме того, вы должны также разрабатывать, тестировать и развертывать поверх одной и той же базы данных (обычно это PostgreSQL в Heroku), вам даже следует использовать те же версии сервера базы данных.Существуют и другие различия между базами данных (например, поведение GROUP BY), от которых ActiveRecord вас не изолирует.Возможно, вы уже делаете это, но я все равно упомянул об этом.

4 голосов
/ 10 июня 2017

Несмотря на то, что принятый ответ превосходен, я хотел бы добавить здесь ответ, который, как мы надеемся, лучше подходит для оригинального вопроса 2, посвященного постерам, для таких экспертов, как я.

Как создать миграцию для замены типа этого столбца

создание миграции скаффолдов

Вы можете создать миграцию для хранениявнесите изменения, набрав в консоли (просто замените table для имени таблицы и column для имени столбца)

rails generate migration change_table_column

Это создаст миграцию скелета внутри вашего приложения Rails / db / migrate/ папка.Эта миграция является заполнителем вашего кода миграции.

Например, я хочу создать миграцию для изменения типа столбца с string на text в таблице с именем TodoItems:

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

Запуск вашегоМиграция

После ввода кода для изменения столбца просто запустите:

rake db:migrate

Чтобы применить миграцию.Если вы допустили ошибку, вы всегда можете отменить изменение с помощью:

rake db:rollack

Методы вверх и вниз

Принятые ссылки на ссылки Up и Down методывместо более нового Change метода.Поскольку рельсы 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:)

...