sea-orm icon indicating copy to clipboard operation
sea-orm copied to clipboard

`find_also_related()` with non null relation, or using inner join, should not return Option

Open jacob-pro opened this issue 2 years ago • 2 comments

Motivation

I have a foreign key that looks like:

.col(ColumnDef::new(Session::UserId).big_integer().not_null())
...
ForeignKeyCreateStatement::new()
    .from(Session::Table, Session::UserId)
    .to(User::Table, User::Id)

The SQL constraints should mean that every session is associated with a user.

I would like to select sessions with their associated user, so that I get (Session, User), but when I use find_also_related() it returns (Session, Option<User>).

Then I looked at the code behind find_also_related and can see it is using a left join:

self.left_join(r).select_also(r)

What I was really looking to do is an inner join:

self.inner_join(r).select_also(r)

But the problem is that the select_also still returns an Option even after doing an inner_join, surely the User can never be None?

It would be great if there could be an API to make this a bit friendlier?

Additional Information

See also:

  • https://github.com/SeaQL/sea-orm/issues/464
  • https://github.com/SeaQL/sea-orm/pull/807

jacob-pro avatar Nov 06 '22 19:11 jacob-pro

Welcome. I agree we should have an equivalent for inner joins. The original concern was, there is no simple way to guarantee a related item always exist. With inner join, we can eliminate that concern.

We can do:

  1. have a new selector SelectBoth in which the return type is Vec<(E::Model, F::Model)>
  2. have a new method fn select_both<F>(mut self, _: F) -> SelectBoth<E, F> on Select
  3. have a new method fn inner_join_and_select<R>(self, r: R) -> SelectBoth<E, R> (sadly the name is not consistent with find_xxx_related, but I could not think of a better self-explanatory name)

PR is welcomed

tyt2y3 avatar Nov 07 '22 14:11 tyt2y3

Hey, I'm working on it. I'll submit a PR asap !

ProbablyClem avatar May 07 '23 20:05 ProbablyClem