it-swarm.com.ru

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

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

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

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

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

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

спасибо

88
Nick Ginanto

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

208
mu is too short

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

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

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

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

Rails generate migration change_table_column

Это создаст миграцию скелета внутри вашей папки Rails application/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. Поскольку Rails .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 :)

4
Tony Cronin