ActiveRecordで1:nリレーション
ActiveRecordで1:nリレーションのデータを扱います。
テーブル定義
CREATE TABLE kittens ( id int(11) NOT NULL auto_increment PRIMARY KEY, strain_id int(11) default NULL, name VARCHAR(255) ); CREATE TABLE strains ( id int(11) NOT NULL auto_increment PRIMARY KEY, name VARCHAR(255) );
種族(strain)と猫(kitten)が1:nの関連です。
ARクラス
それぞれのActiveRecord::Base派生クラスのbelongs_to,has_manyで関連を宣言します。
- belongs_to
- nの側で利用します。これにより、属するStrainを設定したり取得するためのAPIがKittenに追加されます。
- has_many
- 1の側で利用します。これにより、属するKittenを検索したり、追加したりするためのAPIがStrainに追加されます。
class Kitten < ActiveRecord::Base belongs_to :strain # 何らかの種族に属する。 end class Strain < ActiveRecord::Base has_many :kittens # 何匹かの猫が属する。 end
データ挿入
belongs_to関数により追加されたAPIを利用して、KittenにStrainを設定し保存します。Kittenを保存するとStrainも同時に保存されます。
mike = Strain.new mike.name = "mike" mii = Kitten.new mii.name = "mii" mii.strain = mike # belongs_to 関数により、このAPIが追加される。 mii.save # このとき、"mike"も保存される。 kuro = Kitten.new kuro.name = "kuro" kuro.strain = mike kuro.save
実行後のデータベース:
mysql> select * from strains; +----+------+ | id | name | +----+------+ | 1 | mike | +----+------+ 1 row in set (0.00 sec) mysql> select * from kittens; +----+-----------+------+ | id | strain_id | name | +----+-----------+------+ | 1 | 1 | mii | | 2 | 1 | kuro | +----+-----------+------+ 2 rows in set (0.00 sec)
データの取得
belongs_to関数やhas_many関数で追加されたAPIで、種族から属する猫を探したり、猫の種族を取得したりできます。
# 種族から属する猫を探す。 mike = Strain.find_by_name( "mike" ) mike.kittens.each { |kitten| puts kitten.name } puts "---" # 猫の種族を表示 mii = Kitten.find_by_name( "mii" ) puts mii.strain.name
出力:
mii kuro --- mike