0
votes

I'm using Laravel's eloquent ORM, and I was hoping to be able to return a queried laravel model as an attribute, or more ideally as an eloquent relation. This is what I'm trying to do:

class CalendarEvent extends Model
{
    protected $appends = array('conflicts');

    public function getConflictsAttribute () {
        $conflicts =  CalendarEvent::where('calendar_event_type','=',$this->calendar_event_type)
                      ->where('start','<',$this->end)
                      ->where('end','>',$this->start)
                      ->get();   

        return $conflicts;
    }
}

This is an attempt to get over-lapping calendar events, which would be the conflicting events, returned as an object against each event.

This would then mean any query run would return the conflicts :

$event = CalendarEvent::where('id','=',123)->first()->toJson();
$event; // JSON object should contain conflicting events

This results in a non-laravel 500 error, and a blank page. The storage/logs/laravel is not appended to. My /var/log/site-error.log has this appended during the request:

PHP message: PHP 324. Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP message: PHP 325. Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP message: PHP 326. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP message: PHP 327. array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 328. Illuminate\Support\Collection->Illuminate\Support{closure}() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 329. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP message: PHP 330. Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP message: PHP 331. Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP message: PHP 332. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP message: PHP 333. array_map() /home/vagrant/silverback/ 2016/12/04 14:21:16 [error] 792#0: *42880 FastCGI sent in stderr: "home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 370. Illuminate\Support\Collection->Illuminate\Support{closure}() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 371. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP message: PHP 372. Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP message: PHP 373. Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP message: PHP 374. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP message: PHP 375. array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 376. Illuminate\Support\Collection->Illuminate\Support{closure}() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 377. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP message: PHP 378. Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP message: PHP 379. Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP message: PHP 380. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/larav 2016/12/04 14:21:16 [error] 792#0: *42880 FastCGI sent in stderr: "ck/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP message: PHP 417. array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 418. Illuminate\Support\Collection->Illuminate\Support{closure}() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 419. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP message: PHP 420. Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP message: PHP 421. Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP message: PHP 422. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP message: PHP 423. array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 424. Illuminate\Support\Collection->Illuminate\Support{closure}() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 425. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP message: PHP 426. Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP message: PHP 427. Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Mode 2016/12/04 14:21:16 [error] 792#0: *42880 FastCGI sent in stderr: "e/Database/Eloquent/Model.php:2518 PHP message: PHP 464. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP message: PHP 465. array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 466. Illuminate\Support\Collection->Illuminate\Support{closure}() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 467. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP message: PHP 468. Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP message: PHP 469. Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP message: PHP 470. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP message: PHP 471. array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 472. Illuminate\Support\Collection->Illuminate\Support{closure}() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP message: PHP 473. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP message: PHP 474. Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP message: PHP 475. Illuminate\Database\Eloquent\Model->mu 2016/12/04 14:21:16 [error] 792#0: *42880 FastCGI sent in stderr: "ry\Grammars\MySqlGrammar->wrapValue() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Grammar.php:79 PHP message: PHP 511. Illuminate\Database\Query\Grammars\MySqlGrammar->isJsonSelector() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php:225 PHP message: PHP 512. Illuminate\Support\Str::contains() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php:255" while reading response header from upstream, client: 192.168.42.1, server: silverback.dev, request: "GET /test HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "silverback.dev"

UPDATE: I've decided this just isn't possible using Eloquent ORM. What I'm essentially trying to do is a Mysql like this, attaching as a relationship:

select * from calendar_events as calendar_events_2 where calendar_events_2.start < calendar_events_1.end AND calendar_events_2.end > calendar_events_1.start

Instead I've relunctently opted for a foreach loop to attach the data after it has been fetched. I believe this is my only option.

foreach ($shoot_timeline_data as $shoot) {
    foreach ($shoot->booking_cases as $booking_case) {
        $booking_case->booking->conflicts = CalendarEvent::find_clashes(
            $booking_case->booking->calendar_event_type, 
            $booking_case->booking->start, 
            $booking_case->booking->end,
            [$booking_case->booking->id] // excludes this ID via 'whereNotIn'
        );
    }
}
2
Can you post the error message? Your code seems to be fine. It may be due to missing characters possibly due to format change or something that results in Carbon error and the second or third where clause produces error. Nothing can be clear till exact error message can be read.Donkarnash
I've added some more information about errors, and changed my code example to show what I'm trying ton achieve with eager loading.kirgy

2 Answers

1
votes

The error seems to be arising out of appended attribute, where you are trying to get other model instances in an array. A different approach could be to define a relation on self like

class CalendarEvent extends Model{
    public function conflicts()
    { 
        return  $this->hasMany(CalendarEvent::class)
                ->where('calender_event_type','=', $this->calendar_event_type);
    }
}  

Then you can try to query as

$event = CalendarEvent::where('id','=',123)->with('conflicts')->first()->toJson();  

Haven't tested, but try to see if it works.

EDIT

Try using parameters with lazy loading

$event = CalendarEvent::where('id', '=', 123)->first();
or
$event = CalendarEvent::findOrFail(123);  //it will find the record by given primary key - 123 or fail i.e. throw 'MODELNOTFOUNDEXCEPTION'

$start = $event->start;
$end = $event->end;
$event->load('conflicts', function($query) use ($start, $end){
          $query->where('start', '<', $start)
                ->where('end', '>', $end)
        })->get();
0
votes

You need to return it

class CalendarEvent extends Model
{
    protected $appends = array('conflicts');

    public function getConflictsAttribute () 
    {
        return CalendarEvent::where('calendar_event_type','=',$this->calendar_event_type)
                      ->where('start','<',$this->end)
                      ->where('end','>',$this->start)
                      ->get();   
    }
}