diesel icon indicating copy to clipboard operation
diesel copied to clipboard

`Identifiable` and `BelongsTo` don't compose like `JoinTo` does.

Open sgrif opened this issue 7 years ago • 2 comments

I needed to load some posts, the users who wrote them, the comments left on those posts, and the users who left those comments. Ignoring the "tables can only appear once" restriction (pretend that the second users is avatars or something), I can write this: posts.inner_join(users).inner_join(comments.inner_join(avatars)), which would let me get back (Post, User, (Comment, Avatar). Since I can join from (posts, users) to (comments, avatars), I would expect BelongingToDsl and GroupedBy to behave similarly. We should make this code work (I've added additional intermediate vars and type annotations for clarity):

let posts_and_user: Vec<(Post, User)> = posts::table
    .order(posts::published_at.desc())
    .filter(posts::published_at.is_not_null())
    .inner_join(users::table)
    .load(&conn)?;

let comments_and_user: Vec<(Comment, User)> = Comment::belonging_to(&posts_and_user)
    .inner_join(users::table)
    .load(&conn)?;

let grouped_comments_and_user: Vec<Vec<(Comment, User)>> = comments_and_user
    .grouped_by(&posts_and_user);

let everything: Vec<(Post, User, Vec<(Comment, User)>)> = posts_and_user
    .into_iter()
    .zip(comments_and_user)
    .collect();

sgrif avatar Dec 20 '17 19:12 sgrif

There doesn't appear to be an obvious solution here unless we get some changes landed in the language. Attempting to implement Identifiable for tuples just causes Rust to blow up trying to recurse for no reason.

sgrif avatar Jan 19 '18 18:01 sgrif

I think I'm hitting this use case, what is the recommended or idiomatic way to do this now?

danipozo avatar Oct 30 '19 19:10 danipozo