【Rails:7】データベースとモデル(応用編)

リレーションシップ

  • リレーションシップ
    テーブルとテーブルの関連のこと。
  • 外部キー
    別のテーブルの主キーを参照するフィールド。
    • 参照先テーブル(entries)
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
# @entryに属する全コメントの配列
@comment = Comment.find(1)

@entry = @comment.entry
# @commentが属するエントリ
    • 外部キー制約
      参照されているレコードが削除されないようにする等、テーブル間のリレーションシップの整合性を保つ機能。
      次のような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_table_b)
table_a_id table_b_id
48 23
24 46
9 18
  • 命名規約
    • 外部キー名
      参照先テーブル名_id の形にするか、
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
  # @obj3がsaveできなかった場合、@obj1と@obj2のsaveもロールバック
end