Ruby on Rails: テーブル間のリレーションシップ has_many belongs_to, has_one, has_and_belongs_to_many
ショッピングサイトを作るにあたっては避けて通れないややこしい概念だけど、調べてみたら面白い。
今回はUserとOrderの関係から探ってみた。
Userは複数のOrderをするので、Userモデルには has_many :orders, Orderモデルにはbelongs_to :userとするのが定石
まずは、Migration
lass CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.string :emailt.timestamps
end
enddef self.down
drop_table :users
end
end
class CreateOrders < ActiveRecord::Migration
def self.up
create_table :orders do |t|
t.string :name
t.integer :user_idt.timestamps
end
enddef self.down
drop_table :orders
end
end
この二つを作る
#rake db:migration コマンドにてテーブル作成
app/model/order.rb
class Order < ActiveRecord::Base
belongs_to :user
end
app/model/user.rb
class User < ActiveRecord::Base
has_many :orders
end
has_many :orders宣言によってUserクラスには
orders
orders<<
orders.push
orders.replace
orders.delete
orders.delete_all
orders.destroy_all
orders.clear
orders.find
orders.count
orders.size
orders.length
orders.empty?
orders.sum
orders.uniq
orders.build
orders.create
これだけのメソッドが追加される。一対多関係なのでuserからすれば沢山のorderが存在するわけで、それをいじり倒すメソッドが必要というわけだ。
まずはコンソールで検証してみよう
>script/console
Loading development environment (Rails 2.1.1)
>> a = User.new
a = User.new
=> #
まずは空っぽのUserインスタンスが生成される。
>> a.orders
a.orders
=> []
子のArrayクラスを返すがまだ何もない。
>> a.orders.build
a.orders.build
=> #
>> a.orders
a.orders
=> [#]
buildメソッドは新たにorderオブジェクトをを生成し(セーブはしない)userへリンクさせる。
>> a.orders.build
a.orders.build
=> #
>> a.orders
a.orders
=> [#, # ]
もう一回buildするともう一個くっつく
>> a.save
a.save
=> true
>> a
a
=> #
>> a.orders
a.orders
=> [#, # ]
セーブするとOderオブジェクトたちのuser_idは親のid=4となっていることが分かる。
意外と簡単!