質問

私の作成 bigintstring あるない int)入力の主キーのフィールドレールを3.

私た構造のデータは、例えば:

things
------
id bigint primary_key
name char(32)

のアプローチになっていましたように押し:

create_table :things, :id => false do |t| # That prevents the creation of (id int) PK
  t.integer :id, :limit => 8 # That makes the column type bigint
  t.string :name, :limit => 32
  t.primary_key :id # This is perfectly ignored :-(
end

列の型が正しいものの、主キーのオプションは存在するsqlite3、この場合MySQLです。

役に立ちましたか?

解決

少し前にそれを持っていて、ここで答えを見つけました: レールを使用して、整数型の列にならないように主キーを設定するにはどうすればよいですか?

Primary_key:falseを設定し、移行を実行する前にカスタムステートメントを使用する必要があります。

編集1: 実行する正確なクエリについては、データベースドキュメントを確認する必要があります。通常のSQLステートメントとして実行され、データベース固有である必要があります。私が言及した質問の例は、GRE後のSQL用です。 mysqlを使用している場合は、それを変更する必要がある場合があります。

他のヒント

同じ問題がありました。テーブルにとって最も簡単な方法だと思います

accounts 
id bigint primary key 
name char 

create_table :accounts do |t|
t.string :name
end
change_column :accounts, :id , "bigint NOT NULL AUTO_INCREMENT"

MySQLの場合、「bigint unsigned not null auto_increment」のエイリアスである「シリアル」を使用できます。

class ChangeUserIdToBigint < ActiveRecord::Migration
  def change
    change_column :users, :id, 'SERIAL'
  end
end

skalogirouの回答 は良いのですが、変更は反映されませんschema.rb.そのような仕事をするようになった db:schema:loaddb:test:clone を同一のDB構造です。

のに必要な回避策を強化 db:schema:load データベースのスキーマとデータ試験:クローンレーキの作業を行っているとされて:http://www.lshift.net/blog/2013/09/30/changing-the-primary-key-type-in-ruby-on-rails-models/

そして、自分の書いた文章に基づき使用されている回避策:

namespace :my_app do
  namespace :db do
    task :after_schema_load_and_db_test_clone => :environment do
    puts 'Changing primary key for :my_table'
    query = 'ALTER TABLE <my_table> CHANGE id id bigint DEFAULT NULL auto_increment'
    ActiveRecord::Base.connection.execute(query)
  end
end


Rake::Task['db:schema:load'].enhance do
  ::Rake::Task['my_app:db:after_schema_load_and_db_test_clone'].invoke
end

Rake::Task['db:test:clone'].enhance do
  ::Rake::Task['my_app:db:after_schema_load_and_db_test_clone'].invoke
end

すべてのテーブルをPostgresで変換する場合は、このコードを実行する必要があります

class ConvertIntToBigint < ActiveRecord::Migration[5.1]
  def up
    query = <<-SQL
      SELECT tablename AS "tablename"
      FROM pg_tables
      WHERE schemaname = 'public';
    SQL
    connection.execute(query).each do |element|
      if column_exists?(element['tablename'], :id, :integer)
        change_table(element['tablename']) {|t| t.change :id, :bigint }
      end
    end
  end

  def down
  end
end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top