Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MiguelStevens's avatar

Modifying a hasMany() to return a row for each date in a relation

I have an Event model, that has many Dates. A Date has a from and to field, spanning over multiple days.

I would like to have it so that for every day in a Date, my hasmany returns that day. I have no idea how to even get started on this, can someone nudge me in the right direction? Thanks

0 likes
3 replies
JohnBraun's avatar

Could you elaborate a bit more on the actual behaviour of the piece of code you're trying to write?

MiguelStevens's avatar

@johnbraun Sure! a Dates model could have a from='20 July 2019' to='25 july 2019'. so when I query the $event->dates(), it should return 5 rows, because there's 5 days in that row

So I need to modify or build upon the hasMany() to return a row based on the result it gets, I hope that's more clear? Thanks

JohnBraun's avatar

@miguelstevens That's completely possible!

Laravel ships with the DateTime library called Carbon. This library has a CarbonPeriod class, which does exactly what you want.

You can use it in the following way:


use Carbon\Carbon;
use Carbon\CarbonPeriod;

$start = Carbon::parse('20 july 2019');
$end = Carbon:parse('25 july 2019');

$period = CarbonPeriod::between($start, $end);

$dates = collect($period)->map(function ($date) {
    return $date->format('d-m-Y');
});

/** $dates is now equal to: 
 [
       "20-07-2019",
       "21-07-2019",
       "22-07-2019",
       "23-07-2019",
       "24-07-2019",
       "25-07-2019",
     ]
**/

However, if you're retrieving the start and end dates from an eloquent model, you can define the column names to be cast to dates already in your base model class:

// Model.php

protected $dates = ['start', 'end'];

Then, you don't have to parse the date first, but directly use them:

use Carbon\CarbonPeriod;

$period = CarbonPeriod::between($model->start, $model->end);

$dates = collect($period)->map(function ($date) {
    return $date->format('d-m-Y');
});

Please or to participate in this conversation.