Closed8

seaorm で多対多のデータを取得

icy-mountainicy-mountain

こういうER図のデータがあったときに

job に紐づく skill_tag を取得する処理を,seaorm で実装したい

icy-mountainicy-mountain
icy-mountainicy-mountain

sea-orm-cli generate entity -o src/dir
でDBのスキーマをもとにエンティティを生成した場合,以下のような Related トレイトが書かれていると思うけど,load_many_to_manyを使用する場合は記述を追加する必要があるらしい.

job_skill_tag.rs
impl Related<super::job::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::Job.def()
    }
}

impl Related<super::skill_tag::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::SkillTag.def()
    }
}
icy-mountainicy-mountain

今回は job -- job_skill_tag -- skill_tag という関係なので,
seaorm の GitHub の例を見習って job と skill_tag にそれぞれ Related トレイトを実装する

job.rs
impl Related<skill_tag::Entity> for job::Entity {
    fn to() -> RelationDef {
        job_skill_tag::Relation::SkillTag.def()
    }

    fn via() -> Option<RelationDef> {
        Some(job_skill_tag::Relation::Job.def().rev())
    }
}
skill_tag.rs
impl Related<job::Entity> for skill_tag::Entity {
    fn to() -> RelationDef {
        job_skill_tag::Relation::Job.def()
    }

    fn via() -> Option<RelationDef> {
        Some(job_skill_tag::Relation::SkillTag.def().rev())
    }
}
icy-mountainicy-mountain

あとは実際にデータを取得する処理を実装する

icy-mountainicy-mountain
let jobs: Vec<job::Model> = Job::find()
            .order_by_desc(job::Column::Id)
            .all(&self.db.connection())
            .await
            .map_err(|e| ApplicationJobError::FailedToFetchDataFromDb(e.to_string()))?;

let skill_tags: Vec<Vec<skill_tag::Model>> = jobs
            .load_many_to_many(SkillTag, JobSkillTag, &self.db.connection())
            .await
            .map_err(|e| ApplicationJobError::FailedToFetchDataFromDb(e.to_string()))?;
このスクラップは2023/06/12にクローズされました