Many Slick joins:
for {
((((a, b), c), d), e) <-
qa.filter(_.m == x) join
qb on (_.m === _.id) join
qc on (_._1.u === _.uid) join
qd.filter(_.rid == uid) on (_._1._1.u === _.aid) joinLeft
qe on (_._1._1._1.u === _.uid)
} yield (c, d, e)
a couple of problems:
- the
_._._._1
that keeps growing the more joins there are; - the
((((a, b), c), d), e)
making it difficult to work out which one corresponds to which join
Question:
How to make it better? Does the code smell to you? Really great if yes - what patterns should I use instead?
You could write for example something like this:
In
query1
we use implicit inner joins to join over the four tablesa
,b
,c
andd
. Then we can use this query and combine it with another one. In your case a left outer join on tablee
, which leads toquery2
. Finally you execute the resultingquery2
on your database. This way you can combine as many queries as you want.PS: I probably mixed up the join conditions in
query1
. The principle keeps the same.PPS: In
query1
we use monadic joins. The same result can be achieved using applicative joins. IMHO monadic joins are preferable, since the readability is better. Also it saves you a few characters. See http://slick.typesafe.com/doc/3.0.0/queries.html for more information about joining and querying.To catch up the question from the comments:
As I mentioned before, you can combine as many queries you want. The scenario you described could look like this:
AFAIK this is the only method combining inner and outer joins, as there is no such a thing as a monadic outer join. Applicative joins require to have a left and a right side. E.g
queryLeft joinLeft queryRight on ...
. IfqueryLeft
depends on other joins, you must write that query in the first place.