CakePHP 3 findery

W artykule przybliżę nieco tworzenie własnych finderów. Jest to warstwa abstrakcji dla często wykonywanych zapytań. Można wtedy użyć po prostu nazwy naszego customowego findera. Findery tworzymy jako metody w pliku Table (można też je tworzyć w behaviorach). Ich nazwa musi się zaczynać od słowa find. Spójrz na poniższy przykład. Nasze findery to metody findOwnedBy i findPublished.

class ArticlesTable extends Table
{

    public function findOwnedBy(Query $query, array $options)
    {
        $user = $options['user'];
        return $query->where(['author_id' => $user->id]);
    }
    
    public function findPublished(Query $query, array $options)
    {
        return $query->where(['published' => true]);
    }

}

// In a controller or table method.
// Prior to 3.6.0
$articles = TableRegistry::get('Articles');

$articles = TableRegistry::getTableLocator()->get('Articles');
$query = $articles->find('ownedBy', ['user' => $userEntity]);
Przy używaniu finderów można wykorzystać wiele z nich (tzw. stack). Na przykład:
$articles = TableRegistry::getTableLocator()->get('Articles');
$query = $articles->find('published')->find('ownedBy');

Dynamiczne findery

ORM CakePHP dostarcza mechanizm tzw. dynamicznych finderów. Pozwalają one na tworzenie prostych i przydatnych zapytań bez pisania dodatkowego kodu. Zobaczmy jak to wygląda w praktyce. Przykładowo w kontrolerze.
$query = $this->Users->findByUsername('user1');
$query = $this->Users->findAllByUsername('john_doe55');
Jeśli w modelu jest pole username powyższe metody będą szukały po polu username. Ten sam przykład w metodzie Table.
$users = TableRegistry::getTableLocator()->get('Users');
$query = $users->findByUsername('user2');
$query = $users->findAllByUsername('usr1');
Używając dynamicznych finderów możemy aplikować warunki do wielu pól.
$query = $users->findAllByUsernameAndApproved('user1', 1);
$query = $users->findAllByUsernameOrEmail('user2', '[email protected]');