猫でもわかるWeb開発・プログラミング

本業エンジニアリングマネージャー。副業Webエンジニア。Web開発のヒントや、副業、日常生活のことを書きます。

Ruby on Rails 5 の ActiveRecordやmigration で id を string 型にしたいとき、テーブル名を複数形じゃなくて単数形にしたいとき

もくじ

migrationのときにstring型のidを使いたいとき

Ruby on Rails で

rails generate migration <マイグレーションクラス名>

ってしたあとにファイルにテーブル定義を書いていく事を考えます。このとき、デフォルトのままだとint型でauto incrementかつprimary keyなidという属性が勝手に追加されますが、必ずしもそのようなidを使いたくない場合もあるでしょう。例えば、string型のidを使いたい場合の定義はこうです。

とりあえずマイグレーションクラスを生成します。

rails generate migration CreateChampion

マイグレーションクラス名は何でも良いですが、動作+テーブル名 みたいな感じがいいでしょう。今回は champion テーブルを作成するので CreateChampion としました。

db/migrate/20180815052519_create_champion.rb みたいなファイルができるので中身を書きます。

class CreateChampion < ActiveRecord::Migration[5.1]
  def up
    create_table :champion, id: false do |t|
      t.string :id
      t.string :name_jp, index: true
      t.string :version, index: true
      t.string :body
    end
    execute "ALTER TABLE champion ADD PRIMARY KEY (id);"
  end

  def down
    drop_table :champion
  end
end

多分最初は def change が定義されていると思いますが、今回の場合 updown をちゃんと定義する必要があるのでupとdownを定義します。

upではまず、 create_table :champion とするのですが、 id: false をつけます。これにより、デフォルトの、intでauto incrementなidが自動でつかないようにします。

その後、改めてstring型でidを定義しなおして、テーブル作成後に alter table で id を primary key に指定するようにします。(もしかしたらもっときれいな方法があるかもしれませんが...あったら教えてください)

この書き方の場合、downも自分で書く必要があるので、downはdrop_tableとします。

テーブル名を単数形にしたい場合

マイグレーション

テーブル名を単数形にしたい場合は、

class CreateChampion < ActiveRecord::Migration[5.1]
  def up
    create_table :champion, id: false do |t|

というように、 create_table :champion と書き換えます。これがデフォルトのままだと :champions と複数形になてっています。

Ruby on Railsの命名規則ですと、テーブル名は複数形になるのですが、一般的にテーブル名は単数形のほうが多いかと思います。わざわざ単数 - 複数の単語をマッピングするのも面倒ですし*1、そもそも複数にすると違和感のある単語をテーブル名に使うこともあるでしょう。

ActiveRecord

ActiveRecordの方は、通常クラス名を複数形にしたテーブル名が自動的にマッピングされるのですが、今回の場合明示的に対応関係を渡してやる必要があります。

class Models::Champion < ActiveRecord::Base
  self.table_name = 'champion'
end

こういう感じです。

改訂3版基礎 Ruby on Rails (KS IMPRESS KISO SERIES)

改訂3版基礎 Ruby on Rails (KS IMPRESS KISO SERIES)

*1:datum - data みたいな不規則変化がめんどくさい