Rails Composite Primary Keysの table migration
備忘録
あんまり個人的には利用していないComposite Keyのサンプルにdatabaseの記載がすくなかったため、備忘録として記載。複合Keyあんまり使うケースがないんだよなと思いつつ。
0. 環境
name | version |
---|---|
rails | 7.2.1.1 |
mysql | 8.4 |
1. Model構成
Rails Guideをベース作成します。
Bookじゃなくて、OrderItemにしましたが。
$ rails g model Order shop_id:integer id:integer status:string --skip-migration
$ rails g model OrderItem title:string order_id:integer order_shop_id:integer --skip-migration
Loading development environment (Rails 7.2.1.1)
class Order < ApplicationRecord
end
class OrderItem < ApplicationRecord
end
2. Migrationの生成
Rails Guide上の言及にもとづいてModelを生成します。
However, if the above requirements are not met or you would like to use the full composite primary key in associations, you can set the foreign_key: option on the association. This option specifies a composite foreign key on the association; all columns in the foreign key will be used when querying the associated record(s).
Rails Guide edegeの内容をもとに記載します。
2-1. orders tableの生成
$ rails generate migration CreateOrder shop_id:integer id:integer status:string
class CreateOrder < ActiveRecord::Migration[7.2]
def change
create_table :orders do |t|
t.integer :shop_id
t.integer :id
t.string :status
t.timestamps
end
end
end
上記の内容をRails Guide edegeに基づいて修正します。
class CreateOrder < ActiveRecord::Migration[7.2]
def change
create_table :orders, primary_key: [:id, :shop_id] do |t|
t.integer :shop_id
t.integer :id
t.string :status
t.timestamps
end
end
end
2-2. order_items tableの生成
$ rails g migration CreateOrderItem title:string order_id:integer order_shop_id:integer orders:references
class CreateOrderItem < ActiveRecord::Migration[7.2]
def change
create_table :order_items do |t|
t.string :title
t.integer :order_id
t.integer :order_shop_id
t.references :orders, null: false, foreign_key: true
t.timestamps
end
end
end
class CreateOrderItem < ActiveRecord::Migration[7.2]
def change
create_table :order_items do |t|
t.string :title
t.integer :order_id, null: false
t.integer :order_shop_id, null: false
t.foreign_key :orders, primary_key: [:id, :shop_id]
t.timestamps
end
end
end
3. 確認
Guideに記載の通り、少し癖があるのですが、rails consoleを利用して、確認していきます。
% rails c
api(dev)> Order.create(id:[ 1, 1], status: "a")
api(dev)> o = Order.first
api(dev)> o.order_items.create(title: "title", order_id: o.id, order_shop_id: o.shop_id)