I have the following tables
categories
- id
- parent_id
threads
- id
- title
- category_id
- updated_at
The categories table consists of children and parent categories and each thread belongs to a children category.
For each category ( either parent or children ) i want to fetch the thread that was most recently updated. Therefore, when i query all categories, i need to have an extra field which contains the title of that thread.
To better illustrate this, i will give an example.
-
parent_categoty = iOS
-
children_category = iOS13
-
children_category = iOS14
Now when i fetch all categories (iOS, iOS13 and iOS14 ), i want to have an extra field named 'recentThread'. However since threads belong to children_categories, the parent_category doesn't have any thread associated with it, but instead for the parent_category i want to fetch the most recent thread among its children categories.
Therefore i need to use a different relationship based on whether the parent_id is NULL.
public method recentThreadForParent(){
return $this->hasOneThrough(
Thread::class,
Category::class,
'parent_id',
'category_id'
)->latest('updated_at');
}
public method recentThreadForChildren(){
return $this->hasOne(Thread::class)->latest('updated_at');
}
After i did a research i found the following
public method scopeWithRecentTrhead($query){
if ($this->parent_id == null ){
// do something
}
else {
// do something else
}
}
But it is always null so it enters always the firs condition.
On top of that i want in the end to have the same name for either relationship in order to be able to access the recent thread like this
$category->recentThread
Where category can be either parent or children. The solution that i found for this is to use addSelect
public method scopeWithRecentThread($query){
// For the children category
$query->addSelect([
'recentThread' => Thread::select('title')
->whereColumn('category_id', 'categories.id')
->orderBy('updated_at', 'desc')
->limit(1)
]);
// For the parent category im not sure how to do it because i need the ids of the children for each parent category. ( this is the hasOneThrough relationship )
$query->addSelect([
'recentThread' => Thread::select('title')
->whereIn('category_id', 'Ids of children')
->orderBy('updated_at', 'desc')
->limit(1)
]);
}
and in that case i don't know how to conditionally execute a different query.
i've tried to use when but what i need to achieve is something like
$query->when('parent_id is NOT NULL')
But that doesn't work either