diesel
diesel copied to clipboard
`Identifiable` and `BelongsTo` don't compose like `JoinTo` does.
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();
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.
I think I'm hitting this use case, what is the recommended or idiomatic way to do this now?