Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot define multiple columns within the same table that have the same relationship to another table #218

Closed
graysonhead opened this issue Sep 30, 2021 · 3 comments

Comments

@graysonhead
Copy link

graysonhead commented Sep 30, 2021

Hey there, currently migrating one of my projects over from Diesel to take advantage of tokio and I'm running into a problem with one of my tables.

Here is the table in question:

(Irrelevant columns omitted for brevity)

CREATE TABLE attackers (
    attacker_id BIGINT unsigned PRIMARY KEY UNIQUE NOT NULL AUTO_INCREMENT,
    ship_type_id BIGINT unsigned,
    weapon_type_id BIGINT unsigned,
    FOREIGN KEY (ship_type_id) REFERENCES esi_types (type_id),
    FOREIGN KEY (weapon_type_id) REFERENCES esi_types (type_id)
);

The generated attackers.rs entity is generated as so:

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    CharacterPublicInfo,
    #[sea_orm(
        belongs_to = "super::esi_types::Entity",
        from = "Column::ShipTypeId",
        to = "super::esi_types::Column::TypeId",
        on_update = "Restrict",
        on_delete = "Restrict"
    )]
    EsiTypes,
    #[sea_orm(
        belongs_to = "super::esi_types::Entity",
        from = "Column::WeaponTypeId",
        to = "super::esi_types::Column::TypeId",
        on_update = "Restrict",
        on_delete = "Restrict"
    )]
    EsiTypes,
}

This looks correct, but EsiTypes is defined twice in the enum which is of course not possible.

As expected, the related implementation for the other table type is also duplicated:

impl Related<super::esi_types::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::EsiTypes.def()
    }
}

impl Related<super::esi_types::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::EsiTypes.def()
    }
}

I dug around in the API docs a bit, but I can't seem to find a way to make this schema work. Is there a mechanism to allow this in sea_orm?

@tyt2y3
Copy link
Member

tyt2y3 commented Sep 30, 2021

Hi there, welcome!

The codegen is a little dumb now indeed.

Basically, it can't be done with Related, but only the Linked trait. The difference is, a pair of Entity can have multiple links, but only one relation.

pub struct CakeToFilling;
impl Linked for CakeToFilling {
type FromEntity = super::cake::Entity;
type ToEntity = super::filling::Entity;
fn link(&self) -> Vec<RelationDef> {
vec![
super::cake_filling::Relation::Cake.def().rev(),
super::cake_filling::Relation::Filling.def(),
]
}
}

sea-orm/src/query/join.rs

Lines 286 to 301 in a6dfb41

fn join_12() {
assert_eq!(
cake::Entity::find()
.find_also_linked(entity_linked::CakeToFilling)
.build(DbBackend::MySql)
.to_string(),
[
r#"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,"#,
r#"`filling`.`id` AS `B_id`, `filling`.`name` AS `B_name`, `filling`.`vendor_id` AS `B_vendor_id`"#,
r#"FROM `cake`"#,
r#"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id`"#,
r#"LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id`"#,
]
.join(" ")
);
}

See also #89.

Oh btw, is that a Battleship game?

@tyt2y3
Copy link
Member

tyt2y3 commented Oct 4, 2021

Did that help?

@graysonhead
Copy link
Author

Sorry for the delayed reply, been a bit busy lately to work on side projects. It looks like exactly what I'm looking for, and I'll give it a shot once I get a chance to work on this (hopefully in the next few days.)

Its a PVP statistics tracking system for the MMO Eve online.

Thanks for the help!

@SeaQL SeaQL locked and limited conversation to collaborators Oct 16, 2021
@tyt2y3 tyt2y3 closed this as completed Oct 16, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants