6
6

More than 5 years have passed since last update.

Railsで関係性をもったテーブルの作成方法

Posted at

概要

RailsのGenerateでテーブルを作成するとき、1対多とか、多対多の関係を持ったテーブル作成、モデルの書き方に迷った時のためのメモ

テーブル作成

RailsのGenerateを使って、モデルとマイグレーションファイルを作成します。
ついでに、モデルには関連定義(has_many、belongs_toなど)を記述しておきます。

作成するテーブルの関係

テーブル 関係 テーブル
ヘッダテーブル 1対多 詳細テーブル
所属テーブル 1対多 所属テーブル
所属テーブル 多対多 ユーザテーブル
ユーザテーブル 同定義 ゲストテーブル

作成手順(Generate)と作成されるマイグレーション、モデルファイルの中身

ヘッダテーブル
bundle exec rails g model header title:string

上記Generateで作成されるファイル

db/migrate/xxxxx_create_headers.rb
class CreateHeaders < ActiveRecord::Migration
  def change
    create_table :headers do |t|
      t.string :title

      t.timestamps null: false
    end
  end
end
app/models/header.rb
class Header < ActiveRecord::Base
  has_many :details  # <== 関係を追記
end

詳細テーブル
bundle exec rails g model detail header:refelences name:string stock:integer

上記Generateで作成されるファイル

db/migrate/xxxxx_create_details.rb
class CreateDetails < ActiveRecord::Migration
  def change
    create_table :details do |t|
      t.references :header
      t.string :name
      t.integer :stock

      t.timestamps null: false
    end
  end
end
app/models/detail.rb
class Detail < ActiveRecord::Base
  belongs_to :header  # <== 関係を追記
end

所属テーブル
bundle exec rails g model group name:string description:text group:references

上記Generateで作成されるファイル

db/migrate/xxxxx_create_groups.rb
class CreateGroups < ActiveRecord::Migration
  def change
    create_table :groups do |t|
      t.string :name
      t.text :description
      t.references :group, index: true

      t.timestamps null: false
    end
    add_foreign_key :groups, :groups
  end
end
app/models/group.rb
class Group < ActiveRecord::Base
  belongs_to :group   # <== 関係を追記
  has_many   :groups  # <== 関係を追記
  has_and_belongs_to_many :users  # <== 関係を追記
end

ユーザテーブル
bundle exec rails g model user name:string email:string

上記Generateで作成されるファイル

db/migrate/xxxxx_create_users.rb
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps null: false
    end
  end
end
app/models/user.rb
class User < ActiveRecord::Base
  has_and_belongs_to_many :groups  # <== 関係を追記
end

所属-ユーザ対照テーブル
bundle exec rails g migration create_groups_users group:references user:references

上記Generateで作成されるファイル

db/migrate/xxxxx_create_groups_users.rb
class CreateGroupsUsers < ActiveRecord::Migration
  def change
    create_table :groups_users, id: false do |t|
      t.references :group, index: true, null: false
      t.references :user,  index: true, null: false
    end
    add_foreign_key :groups_users, :groups
    add_foreign_key :groups_users, :users
  end
end

ゲストテーブル
bundle exec rails g model guest name:string email:string

上記Generateで作成されるファイル

db/migrate/xxxxx_create_guests.rb
class CreateGuests < ActiveRecord::Migration
  def change
    create_table :guests do |t|
      t.string :name
      t.string :email

      t.timestamps null: false
    end
  end
end
app/models/guest.rb
class Guest < ActiveRecord::Base
end

モデルへのスキーマコメント付与

annotateGemをバンドルしておけば、bundle exec annotateで、モデルにスキーマ定義をコメントとして付与できます。
上記、app/models/user.rbの場合、以下のようになります。

app/models/user.rb
# == Schema Information
#
# Table name: users
#
#  id         :integer          not null, primary key
#  name       :string(255)
#  email      :string(255)
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups
end

これで、カラムを確認するために、わざわざスキーマファイルを見る必要が無くなります。

DB作成とマイグレート

開発環境developmentへのDB作成、マイグレートを行います。

DB作成
bundle exec rake db:create RAILS_ENV=development
マイグレート
bundle exec rake db:migrate RAILS_ENV=development

6
6
0

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
6
6