Reputation: 6435
How can I use the first()
method on a relation in an Eloquent query builder?
I only want to return the first section and the first subsection within that section.
I have the following query in my Assessment service:
public function firstSubsection()
{
return $this->model->with(['sections.subsections' => function ($q) {
$q->take(1);
}])->first();
}
This returns multiple sections:
{
"id": 1,
"name": "Assessment 1",
"description": "<p>Some description</p>",
"created_at": "2018-03-09 17:14:43",
"updated_at": "2018-03-09 17:14:43",
"sections": [
{
"id": 5,
"name": "Section 1",
"description": null,
"parent": null,
"created_at": "2018-03-09 17:14:52",
"updated_at": "2018-03-09 17:14:52",
"pivot": {
"assessment_id": 1,
"section_id": 5
},
"subsections": [
{
"id": 6,
"name": "Subsection 1",
"description": "<p>Lorem ipsum dolor sit amet<br>\r\n</p>",
"parent": 5,
"position": 6,
"created_at": "2018-03-09 17:15:08",
"updated_at": "2018-03-21 11:40:10"
}
]
},
{
"id": 10,
"name": "Section 2",
"description": null,
"parent": null,
"position": 10,
"created_at": "2018-03-20 14:34:50",
"updated_at": "2018-03-20 14:34:50",
"pivot": {
"assessment_id": 1,
"section_id": 10
},
"subsections": []
}
]
}
Any idea how I can achieve this?
I have the following relationships in my Eloquent models:
class Section extends Model
{
use BelongsToSortedManyTrait, SortableTrait;
public $fillable = [
'id',
'name',
'description',
'parent',
'position'
];
public static $rules = [
// create rules
'name' => 'required'
];
public function assessments() {
return $this->belongsToSortedMany('App\Models\Assessment');
}
public function subsections() {
return $this->hasMany(self::class, 'parent')->sorted();
}
}
class Assessment extends Model
{
public $fillable = [
'id',
'name',
'description'
];
public static $rules = [
// create rules
];
public function sections()
{
return $this->belongsToMany('App\Models\Section')->whereNull('parent')->sorted();
}
}
Upvotes: 1
Views: 1773
Reputation: 6435
In the end I had to do it like this:
public function firstSubsection()
{
return $this->model->with(['sections' => function ($q) {
$q->with(['subsections' => function ($q) {
$q->first();
}
])->first();
}])->first();
}
Thanks to @ab_in for leading me in the right direction.
Upvotes: 3
Reputation: 1609
Take(1)
and first()
doing same thing right now. But still its not a problem. Remove take(1)
and add ->get()
after first()
Give it a try.
Upvotes: 0
Reputation: 1642
I am not sure this will work or not, but you can try this logic:
If you want to eager load the first section and subsection of your model you should create a new relationship in your model :
public function firstSectionOnly()
{
return $this->hasOne(Section::class)->orderBy('id', 'asc');
}
And in Section model define
public function firstSubSectionOnly()
{
return $this->hasOne(Subsection::class)->orderBy('id', 'asc');
}
Then you can eager load it in your current model:
public function firstSubsection()
{
return $this->model->with(['firstSectionOnly.firstSubSectionOnly'])->first();
}
After trying this. Tell me it is working or have errors.
Upvotes: 1
Reputation: 93
public function firstSubsection()
{
return $this->model->with(['sections.subsections' => function ($q)
{
$q->take(1)->first();
}])->first();
}
Upvotes: 0