web-dev-qa-db-ja.com

railsの列タイプをより長い文字列に変更する

最初の移行で、列contentが文字列であると宣言しました。

Postgresを使用するherokuにアプリをプッシュした後、コンテンツ内のフォームに255を超える文字列を入力すると、エラーが発生します

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

問題は、そのコンテンツにおそらく非常に長い文字列(フリーテキスト、数千文字になる可能性がある)を含める必要があることです

  1. Pgはどの変数(文字列はこれに適していません)を受け入れますか?
  2. その列のタイプを置き換える移行を作成する方法

ありがとう

88
Nick Ginanto

長さ制限のない文字列が必要な場合は、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を使用すると、データベースがサポートする任意の長さの文字列型を取得できます。 PostgreSQLでは、長さのないvarchar列を使用できますが、ほとんどのデータベースはそのために別の型を使用し、Railsは長さのないvarcharを認識しません。 PostgreSQLで text を取得するには、Railsでtextを使用する必要があります。 PostgreSQLでは、タイプtextの列とタイプvarcharの列の間に違いはありません(ただし、varchar(n)isが異なります)。さらに、PostgreSQLの上にデプロイする場合、_:string_(別名varchar)を使用する理由はまったくありません。データベースは、varchar(n)の余分な長さの制約を除いて、textvarchar(n)を内部的に同じように扱います。列サイズに外部制約(フォーム897/Bのフィールド432は23文字になると言っている政府のフォームなど)がある場合にのみvarchar(n)(別名_:string_)を使用する必要があります。

余談ですが、string列をどこかで使用している場合は、常に_:limit_を指定して、制限があることを確認し、制限を超えないことを確認するためにモデルを検証する必要があります。 。制限を超えると、PostgreSQLは文句を言い、例外を発生させます。MySQLは文字列を静かに切り詰めるか文句を言います(サーバー構成に応じて)、SQLiteはそのまま渡します。 。

また、同じデータベース(通常はHerokuのPostgreSQL)上で開発、テスト、展開する必要があります。同じバージョンのデータベースサーバーを使用する必要もあります。 ActiveRecordがユーザーを隔離しないデータベース(GROUP BYの動作など)には他にも違いがあります。あなたはすでにこれをしているかもしれませんが、とにかくそれを言及すると思いました。

208
mu is too short

受け入れられた答えは優れていますが、私のような非専門家のために、元のポスターの質問パート2をうまく処理できるように、ここに答えを追加したかったのです。

  1. その列のタイプを置き換えるために移行を作成する方法

スキャフォールドマイグレーションの生成

コンソールに入力することで、変更を保持するための移行を生成できます(テーブル名のtableと列名のcolumnを置き換えるだけです)

Rails generate migration change_table_column

これにより、スケルトン移行が生成されますRails application/db/migrate /フォルダー。この移行は、移行コードのプレースホルダーです。

たとえば、TodoItemsという名前のテーブルで、列のタイプをstringからtextに変更する移行を作成します。

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 .2old styleUp and Downメソッドは、新しいChangeメソッドに比べていくつかの利点があります。ダウン 'ActiveRecord::IrreversibleMigration exceptionRails 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 :)

5
Tony Cronin