Wirtualne pola

Pobranie największej/najwcześniejszej lub namniejszej/najpóźniejszej wartości

protected $_accessible = [
   ......
   'schedule_first_date' => true,    // Pierwsza data w harmonogramie
   'schedule_last_date' => true,     // Ostatnia data w harmonogramie
];

// Dla projektu pobiera ostatnią datę z harmonogramu (schedules - tablica powiązanych rekordów)
protected function _getScheduleLastDate()
{
   if (isset($this->_fields['schedule_last_date'])) {
      return $this->_fields['schedule_last_date'];
   }
   if (empty($this->schedules)) { return ; }

   $last_day = (new Collection($this->schedules))->max('date_to')->date_to;
   return $last_day;
}  

// Dla projektu pobiera ostatnią datę z harmonogramu (schedules)
protected function _getScheduleFirstDate()
{
  if (isset($this->_fields['schedule_first_date'])) {
       return $this->_fields['schedule_first_date'];
  }
  if (empty($this->schedules)) { return ; }

  $first_fday = (new Collection($this->schedules))->min('date_from')->date_from;
  return $first_fday;
}

Tworzy wirtualne pole ze zagregowanymi wartościami modelu podrzędnego np. suma wartości pozycji faktury.

use Cake\Collection\Collection;

// dodajemy jeśli chcemy dodawać z formularza
protected array $_accessible = [
    // ...
    'tag_string' => true
];

protected function _getTagString()
{
    if (isset($this->_fields['tag_string'])) {
        return $this->_fields['tag_string'];
    }
    if (empty($this->tags)) {
        return '';
    }
    $tags = new Collection($this->tags);

    $str = $tags->reduce(function ($string, $tag) {
        return $string . $tag->title . ', ';
    }, '');

    return trim($str, ', ');
}