Rails app with Rails generate migrationsコマンドを使用して、テーブルにテーブルを作成しました。このマイグレーションファイルは次のとおりです。
class CreateListings < ActiveRecord::Migration
def change
create_table :listings do |t|
t.string :name
t.string :telephone
t.string :latitude
t.string :longitude
t.timestamps
end
end
end
次に、緯度と経度を整数として保存したかったので、実行してみました。
Rails generate migration changeColumnType
そのファイルの内容は次のとおりです。
class ChangeColumnType < ActiveRecord::Migration
def up
#change latitude columntype from string to integertype
change_column :listings, :latitude, :integer
change_column :listings, :longitude, :integer
#change longitude columntype from string to integer type
end
def down
end
end
列のタイプが変更されることを期待していましたが、レーキが中止され、次のエラーメッセージが表示されました。どうしてこれが通らなかったのかしら?私のアプリでpostgresqlを使用しています。
rake db:migrate
== ChangeColumnType: migrating ===============================================
-- change_column(:listings, :latitude, :integer)
rake aborted!
An error has occurred, this and all later migrations canceled:
PG::Error: ERROR: column "latitude" cannot be cast to type integer
: ALTER TABLE "listings" ALTER COLUMN "latitude" TYPE integer
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
注:テーブルにはデータがありません。ありがとう
私はマニュアルを引用します についてALTER TABLE
:
古いタイプから新しいタイプへの暗黙的または代入キャストがない場合は、USING句を指定する必要があります。
必要なものは:
ALTER TABLEリストALTER経度TYPE整数 Longing :: intを使用する; ALTER TABLEリストALTER緯度TYPE整数 緯度を使用して::整数;
または、1つのコマンドで(大きなテーブルの場合)より短く、より速く:
ALTER TABLE listings ALTER longitude TYPE integer USING longitude::int
,ALTER latitude TYPE integer USING latitude::int;
これは、すべてのエントリがinteger
に変換可能である限り、データの有無に関係なく機能します。
列にDEFAULT
を定義している場合は、それをドロップして、新しいタイプ用に再作成する必要がある場合があります。
これが ActiveRecordでこれを行う方法に関するブログ記事 です。
またはコメントに@muのアドバイスを添えてください。彼は自分のルビーを知っています。私はここでのPostgreSQLだけが得意です。
以下のようにraw SQLを移行ファイルに含めて、schema.rbを更新します。
class ChangeColumnType < ActiveRecord::Migration
def up
execute 'ALTER TABLE listings ALTER COLUMN latitude TYPE integer USING (latitude::integer)'
execute 'ALTER TABLE listings ALTER COLUMN longitude TYPE integer USING (longitude::integer)'
end
def down
execute 'ALTER TABLE listings ALTER COLUMN latitude TYPE text USING (latitude::text)'
execute 'ALTER TABLE listings ALTER COLUMN longitude TYPE text USING (longitude::text)'
end
end
これは少し見づらいですが、列を削除して新しいタイプで再度追加することを好みます。
def change
remove_column :mytable, :mycolumn
add_column :mytable, :mycolumn, :integer, default: 0
end
以下はもっとRails way
問題に取り組みます。私の場合、購入表に2つの列があり、文字列型から浮動小数点型に変換する必要がありました。
def change
change_column :purchases, :mc_gross, 'float USING CAST(mc_gross AS float)'
change_column :purchases, :mc_fee, 'float USING CAST(mc_fee AS float)'
end
それは私にとってはトリックでした。
緯度と経度は10進数です
Rails g scaffold client name:string email:string 'latitude:decimal{12,3}' 'longitude:decimal{12,3}'
class CreateClients < ActiveRecord::Migration[5.0]
def change
create_table :clients do |t|
t.string :name
t.string :email
t.decimal :latitude, precision: 12, scale: 3
t.decimal :longitude, precision: 12, scale: 3
t.timestamps
end
end
end