I'm working on a bus route system with stops at certain locations. The route stops are in a ascending sequence by a 'order' column, as in 1, 2, 3, 4, 5.. etc.
These are my tables:
BUS
id | operator_id | name
1 | 1 | The Big Red Bus
PLACES (some dummy data just for example)
id | name | slug | parent_id
1 | Amsterdam | amsterdam |
2 | London | london |
3 | Stockholm | stockholm |
4 | Helsinki | helsinki |
5 | Dam Square | dam-square | 1
ROUTES
id | name
1 | Amsterdam - London
2 | London - Amsterdam
ROUTE_LOCATIONS (LOCATIONS)
id | route_id | place_id | order | start | end
1 | 1 | 1 | 1 | 1 | 0
2 | 1 | 2 | 2 | 0 | 0
3 | 1 | 3 | 3 | 0 | 0
4 | 1 | 4 | 4 | 0 | 1
User Input The given user input when I start a search to check if we have any available bus routes is a place slug from the PLACES table. For example:
- from: london
- to: dam-square
Below is the query what I tried so far, but I am really unsure on how to build a check/join into the actual query to check if the 'order' sequence is ascending. I just can't get my head around it.
$buses = Bus::whereHas('route.locations.place', function ($query) use ($from, $to) {
$query->where('slug', $from)->where('end', 0);
})->whereHas('route.locations.place', function ($query) use ($from, $to) {
$query->where('slug', $to)->where('start', 0);
})->get();
Relationships structure is as follows:
BUS hasOne ROUTE
ROUTE belongsToMany BUS
ROUTE hasMany LOCATIONS (ROUTE_LOCATIONS TABLE)
I have already tried the following query which works to get available routes, but I really like to do it directly in laravel eloquent with my models, so I can easily use the relationships in my view. I am just unsure on how to go about it.
Below query only works with a place ID instead of a slug, and I really like it to be a slug instead of an ID.
$routes = DB::select('SELECT R.id, R.name
FROM route_locations L
INNER JOIN routes R ON R.id = L.route_id
WHERE
L.place_id = "'.$from->id.'" AND
EXISTS (SELECT id FROM route_locations F WHERE L.route_id = F.route_id AND F.order > L.order AND F.place_id = "'.$to->id.'")');
Does anyone know if this is possible and how?
Thank you!