add a whereHas('parent') to the top level of the query so that the duplicates are ommitted
you might need something else to include alerts with no children
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I'm trying to figure out an elegant way of solving this issue, but my mind has drawn blanks each time:
Let's say I have a table called alerts. An Alert has three properties: A message, a serial, and a parent_serial. The idea being, an alert can be related to another alert via a parent_serial. For example:
[
"message" => "Outage reported",
"serial" => 1,
"parent_serial" => null
],
[
"message" => "Problem identified",
"serial" => 2,
"parent_serial" => 1
],
[
"message" => "Outage resolved",
"serial" => 3,
"parent_serial" => 2
],
[
"message" => "Something else",
"serial" => 4,
"parent_serial" => null
]
So when you get all the alerts with parents, you'd (want to) see something like:
[
"message" => "Something else",
"serial" => 4,
"parents" => []
],
[
"message" => "Outage Resolved",
"serial" => 3,
"parents" => [
"message" => "Problem Identified",
"serial" => 2,
"parents" => [
"message" => "Outage Reported",
"serial" => 1,
"parents" => []
]
]
]
Or in other words, I want to show the newest alert FIRST, then have the "parents" property (recursively) contain the related alerts.
This is easy enough to do by creating a recursive relationship:
public function parents() {
return $this->hasMany(Alert::class, 'serial', 'parent_serial')->with('parents');
}
But then that leads to duplicates:
[
"message" => "Something else",
"serial" => 4,
"parents" => []
],
[
"message" => "Outage Reported",
"serial" => 1,
"parents" => []
],
[
"message" => "Outage Resolved",
"serial" => 3,
"parents" => [
"message" => "Problem Identified",
"serial" => 2,
"parents" => [
"message" => "Outage Reported",
"serial" => 1,
"parents" => []
]
]
],
[
"message" => "Problem Identified",
"serial" => 2,
"parents" => [
"message" => "Outage Reported",
"serial" => 1,
"parents" => []
]
]
Or in other words:
[4, 3, 2, 1, [3 => [2 => [1]]], [2 => [1]]]
tl;dr: I want something similar to a nested comment system, but flipped on its head, so the newest comment is first, then nested within that newest comment is the next oldest comment, and within that, the next oldest, and so on.
Is there an elegant (Eloquent) solution for this? I thought about a foreach within a foreach (and possibly a foreach within that) but no matter what, I always feel there's a better way to do it.
Please or to participate in this conversation.