リレーション

取得時にJOINでのリレーション取得は行わず、クエリー実行後に対象の主キーをまとめて、リレーション先からIN句を使用したクエリーで取得します。

リレーションの取得

取得したオブジェクトや更新用オブジェクト、あるいは Vec<_{モデル名}> などに fetch_{リレーション名} のメソッドを使用すると、そのオブジェクトやリストに必要なリレーションを一回のクエリで取得してそれぞれ元のオブジェクトに保存します。

#![allow(unused)]
fn main() {
let mut list = _{モデル名}::query().select(&mut conn).await?;
list.fetch_{リレーション名}(&mut conn).await?;
}

3世代目の取得

リレーション先のリレーションのような3世代目の取得については Vec<&mut _{モデル名}> にまとめれば fetch_{リレーション名} のメソッドが使用可能です。
その際、2世代目のリレーション先のトレイトが必要になります。 取得された3世代目リレーションのオブジェクトはそれぞれ1世代目オブジェクトが所持する2世代目オブジェクトの下に所持するようになります。

#![allow(unused)]
fn main() {
use {2世代目のリレーションmod}::*;

let mut list = _{1世代目モデル名}::query().select(&mut conn).await?;
list.fetch_{2世代目リレーション名}(&mut conn).await?;
let mut v: Vec<_> = list.iter_mut().map(|v| v.{2世代目リレーション名}()).flatten().collect();
v.fetch_{3世代目リレーション名}(&mut conn).await?;
}

リレーションのタイプ

スキーマに設定するリレーションのタイプとして、one, one_to_one, many に対応しています。

  • one
    自テーブルの主キーではないカラムに他のテーブルの主キーを保持している状態
  • one_to_one
    自テーブルが主であり、従属テーブル側も主キーに自テーブルと同じ値を保持して一対一で結合している状態
  • many
    自テーブルが主であり、従属テーブル側に自テーブルの主キーを保持して一対多で結合している状態

リレーションが外部キー制約としてDDLに生成されないようにする場合は ignore_foreign_key: true を設定します。
なお、one_to_one と many の場合は従属テーブル側に on_delete: cascade を設定可能です。外部キー制約を生成していない場合でもフレームワークにより物理削除に連動して削除されます。

リレーションのキャッシュ

オブジェクトのキャッシュを有効にする場合、 use_cache あるいは in_cache の設定を有効にします。

  • use_cache
    リレーションのタイプが one の場合に設定可能で、まとめてキャッシュはされませんが、キャッシュオブジェクトからリレーション先のオブジェクトのキャッシュを fetch することが出来ます。
  • in_cache
    リレーションのタイプが one_to_one, many の場合に設定可能で、キャッシュ時にまとめてキャッシュされます。

なお、 use_cache の代わりに use_cache_with_trashed を設定することでリレーション先が論理削除されていてもキャッシュを取得できます。 これは、例えば社員を論理削除しても過去にその社員が作成したドキュメントから作成者の名前が消えると困るようなケースで使用できます。