リレーションシップ
- リレーションシップ
テーブルとテーブルの関連のこと。
- 外部キー
別のテーブルの主キーを参照するフィールド。
id(主キー) |
title |
1 |
8/1の日記 |
2 |
8/2の日記 |
3 |
8/3の日記 |
id |
entry_id (外部キー:entriesのidを参照) |
body |
1 |
1 |
おはよう |
2 |
3 |
こんにちは |
3 |
1 |
こんばんは |
@entry = Entry.find(1)
@comments = @entry.comments
@comment = Comment.find(1)
@entry = @comment.entry
-
- 外部キー制約
参照されているレコードが削除されないようにする等、テーブル間のリレーションシップの整合性を保つ機能。
次のようなsql文で設けることができます。
ALTER TABLE comments ADD CONSTRAINT FOREIGN KEY (entry_id) REFFERENCES entries (id)
-
- リレーションによるオブジェクト保存のタイミング
次のコードでは、@commentの保存されるタイミングが2通り考えられます。
@entry.comments << @comment
-
-
- @entryが保存済の場合 ⇒ このコードが呼ばれた時点で、@commentも保存されます。
- @entryが未保存の場合 ⇒ @entryが保存されるとき、@commentも同時に保存されます。
- 他テーブルとのリレーションの宣言
- has_one
1レコードにつき、他テーブルの1レコードからのみ参照されることを意味します。
has_one :mdlname
オプション |
機能 |
:class_name |
モデルクラス名を指定 |
:foreign_key |
外部キー名を指定 |
:dependent |
参照先が削除されたときの挙動 :destroy => 参照元を削除 :delete => モデルクラスの設計を無視して参照元を削除 :nullify => 参照元の外部キーをNULLに |
:conditions |
sql文の条件 |
:order |
ソート基準 |
-
- has_many
1レコードにつき、他テーブルの複数レコードから参照されることを意味します。
has_many :mdlnames
オプション |
機能 |
:class_name |
|
:foreign_key |
|
:dependent |
|
:conditions |
|
:order |
|
:limit |
モデル配列の最大値 |
:offset |
取り出すレコードの始点 |
:through |
参照元の参照元テーブルと1対多で関係付く |
:uniq |
true => 重複した関連付けを無視する |
-
- belongs_to
他テーブルのレコードを参照することを意味します。
belongs_to :mdlname
オプション |
機能 |
:class_name |
|
:foreign_key |
|
:conditions |
|
:order |
|
-
- has_and_belongs_to_many
他テーブルと互いに、複数レコードを参照しあうことを意味します。
has_and_belongs_to_many :mdlnames
オプション |
機能 |
:class_name |
|
:join_table |
結合テーブル名を指定 |
:foreign_key |
結合テーブルの外部キー名(第1テーブル)を指定 |
:association_foreign_key |
結合テーブルの外部キー名(第2テーブル)を指定 |
:conditions |
|
:order |
|
:limit |
|
:offset |
|
:through |
|
:uniq |
|
- リレーションの種類
- 1対1
has_oneとbelongs_toの関係。
-
- 1対多
has_manyとbelongs_toの関係。
-
- 多対多
has_and_belongs_to_manyとhas_and_belongs_to_manyの関係。
テーブルを多対多の関係にする場合、結合テーブルを別途作成し、ふたつのテーブルのidを保存します。
table_a_id |
table_b_id |
48 |
23 |
24 |
46 |
9 |
18 |
belongs_to :mdlname,
:foreign_key => 'mdlname_number'
-
- 結合テーブル名
ふたつのテーブル名をアルファベット順に_で繋ぐか、
has_and_belongs_to_many :mdlnames,
:join_table => 'mdlnames_and_selfnames'
def save_objects
transaction do
@obj1.save
@obj2.save
@obj3.save
end
end