The GPS data I import can have multiple waypoint places for the same place.
I store this GPS data in the database, but want to treat all duplicates as one.
My Laravel (v6) model Place has id
and parent_id
(I could change this if necessary). E.g.
id parent_id name
1 null real place
2 1 same as real place
When querying for Place info, I would always like to do this for the real place and the duplicates. So far I am using a local scope:
public function scopeId($query, $id) {
return $query->where('id', $id)->orWhere('parent_id', $id);
}
This allows me to do e.g. Place::id(1)->with('visits')->get()
which gives me e.g.
place 1
- visit A
- visit B
place 2
- visit C
Is there a way to "merge" these Places so that the responses always return just the parent Place? Like:
place 1
- visit A
- visit B
- visit C
The with('visits')
is an example. Would like this functionality to apply to all Place related queries.
Edit: full example
Place::id(1078)->select('id','parent_id')->with('visits:id,place_id')->get()
=> Illuminate\Database\Eloquent\Collection {#3092
all: [
App\Place {#3115
id: 1068,
parent_id: 1078,
visits: Illuminate\Database\Eloquent\Collection {#3109
all: [
App\Timeline {#3087
id: 8022,
place_id: 1068,
},
App\Timeline {#3094
id: 8023,
place_id: 1068,
},
],
},
},
App\Place {#3137
id: 1078,
parent_id: null,
visits: Illuminate\Database\Eloquent\Collection {#3139
all: [
App\Timeline {#3117
id: 8304,
place_id: 1078,
},
App\Timeline {#3084
id: 8401,
place_id: 1078,
},
App\Timeline {#3116
id: 8513,
place_id: 1078,
},
App\Timeline {#3119
id: 9363,
place_id: 1078,
},
],
},
},
],
}
You can override the
get()
method from Eloquent by creating a new classCustomQueryBuilder
that extends theIlluminate\Database\Query\Builder
:Your customized
get()
method inCustomQueryBuilder
:Create a new class
CustomModel
that extends theIlluminate\Database\Eloquent\Model
and there override thenewBaseQueryBuilder
like this:Finally, Now your Place Model ( or Whichever require this custom
get()
behavior) can extendCustomModel
instead.Now your query will be something like:
Note:
Be aware that all queries made from Models extending your
CustomModel
will get this new behavior, hence I have added a check withneedVisitsCombined()
method.So if you're doing more customization do all the needed checks to don't mess up with Eloquent normal behaviour, something like this