简体   繁体   中英

Laravel Eloquent multiple whereHas on relationship where column 'order' is higher than the previous whereHas

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!

Your code could be rewritten to this one:

$busses = Bus::whereHas('route.locations.place', function ($query) use ($from, $to) {
    $query->where('slug', $from)
        ->where('slug', $to)
        ->where('start', 0)
        ->where('end', 0);
        // here should do a check if the 'order' column is higher than the first wherehas
})->get();

And it doesn't make much sense to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM