LoginSignup
7

More than 5 years have passed since last update.

ActiveRecord 4.1+MySQLで任意のカラムをPKにする

Last updated at Posted at 2014-11-16

ActiveRecord 4.1+MySQLで、特別な拡張を入れなくても任意の名前・型のカラムをPKにできたのでメモしておきます。

書き方

名前だけ変える

primary_key: 'my_id'

create_table "items", primary_key: 'my_id', force: true do |t|
  ...
end

型だけ変える

id: 'bigint primary key auto_increment'

create_table "items", id: 'bigint primary key auto_increment', force: true do |t|
  ...
end

名前・型を変える

primary_key: 'my_id', id: 'bigint primary key auto_increment'

create_table "items", primary_key: 'my_id', id: 'bigint primary key auto_increment', force: true do |t|
  ...
end

ダンプ

ダンプすると名前の情報は出力されますが型の情報(id: xxx)は出力されません。

create_table "items", primary_key: "my_id", force: true do |t|
  ...
end

解説

create_tableでPKの定義を生成しているのが以下の箇所:

schema_statements.rb#L190

unless options[:id] == false
  pk = options.fetch(:primary_key) {
    Base.get_primary_key table_name.to_s.singularize
  }

  td.primary_key pk, options.fetch(:id, :primary_key), options
end

:idfalseでないとき、:primary_keyの値を名前、:idの値を型としてPKを定義しています。

MySQLのネイティブな型の定義は以下の通り:

abstract_mysql_adapter.rb#L152

NATIVE_DATABASE_TYPES = {
  :primary_key => "int(11) auto_increment PRIMARY KEY",
  :string      => { :name => "varchar", :limit => 255 },
  :text        => { :name => "text" },
  :integer     => { :name => "int", :limit => 4 },
  :float       => { :name => "float" },
  :decimal     => { :name => "decimal" },
  :datetime    => { :name => "datetime" },
  :timestamp   => { :name => "datetime" },
  :time        => { :name => "time" },
  :date        => { :name => "date" },
  :binary      => { :name => "blob" },
  :boolean     => { :name => "tinyint", :limit => 1 }
}

実際にSQLを発行するときはtype_to_sqlメソッドでネイティブな型に変換していますが

if native = native_database_types[type.to_sym]
  ...
else
  type.to_s
end

native_database_typesにないものはそのままSQLの型として使われるので、:idに「任意の型」+primary keyを設定すると、任意の型でPKを作成できます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7