Изменение типа столбца на более длинные строки в рельсах

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

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

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

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

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

спасибо

Ответ 1

Вы должны использовать 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 не будет изолировать вас. Возможно, вы это уже делаете, но я думал, что все равно напишу об этом.

Ответ 2

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

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

генерация миграции лесов

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

rails generate migrate change_table_column

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

Например, я хочу создать миграцию, чтобы изменить тип столбца от 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

Принятые ответы ссылаются на методы 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

Наслаждайтесь Rails:)