Dalej poznajemy eloquent ORM oraz Query Builder Laravela pisząc własne komendy. Kontynuacja lekcji poprzednich – do dzieła.

Ok, napiszemy sobie funkcję przyjmującą input:

Artisan::command('where-and-where', function () {

    $firstName = $this->ask('firstName: ');
    $lastName = $this->ask('lastName: ');
    $age = $this->ask('age: ');

    $id =  Person::where('firstName', $firstName)
    ->where('lastName', $lastName)
    ->where('age', $age)
    ->select('id')
    ->first();

    $this->comment("ID youre looking for: {$id['id']}");
});

Ok, wytłumaczenie:

  • Pierwszy where ma scope resolution operator (::) bo zamienia model w chainowalne composable query dla tego modelu
  • każdy następny where (już niestatyczna metoda) dokłada „AND WHERE” do naszego query
  • select pokazuje, że interesuje nas tylko kolumna id
  • first zamienia to wszystko na wynik
  • wynik to {„id”: 5}, trzeba się odwołać po kluczu

Swoją drogą warto znać metodę toSql, dzięki niej możemy debugować nasze queries:

Artisan::command('where-and-where', function () {

    $firstName = $this->ask('firstName: ');
    $lastName = $this->ask('lastName: ');
    $age = $this->ask('age: ');

    $id =  Person::where('firstName', $firstName)
    ->where('lastName', $lastName)
    ->where('age', $age)
    ->select('id')
    ->toSql();

    $this->comment("$id");
});

//select `id` from `people` where `firstName` = ? and `lastName` = ? and `age` = ?

I już widzimy, co się dzieje. Dobra, teraz inny sposób na to samo:

Artisan::command('where-and-where2', function () {

    $firstName = $this->ask('firstName: ');
    $lastName = $this->ask('lastName: ');
    $age = $this->ask('age: ');

    $id =  Person::where([
        ['firstName', $firstName],
        ['lastName', $lastName],
        ['age', $age],
    ])
    ->select('id')
    ->first();

    $this->comment("ID youre looking for: {$id['id']}");
});

Ok, a jak to wygląda w QB (fasada DB)? Podobnie:

$users = DB::table('users')
                ->where('votes', '=', 100)
                ->where('age', '>', 35)
                ->get();

Możemy też przekazać tablicę:

$users = DB::table('users')->where([
    ['status', '=', '1'],
    ['subscribed', '<>', '1'],
])->get();

Jeżeli chodzi o or, to mamy osobną metodę:

$users = DB::table('users')
                    ->where('votes', '>', 100)
                    ->orWhere('name', 'John')
                    ->get();

Ok, a bardziej skomplikowane queries? Będziemy musieli zaimportować buildera, rzućmy okiem na taki kod:

Artisan::command('test-me', function () {
    $sql = DB::table('users')
            ->where('votes', '>', 100)
            ->orWhere(function (Builder $query) {
                $query->where('name', 'Abigail')
                      ->where('votes', '>', 50);
            })
            ->toSql();
    $this->comment($sql);
});

//select * from `users` where `votes` > ? or (`name` = ? and `votes` > ?)

Jeżeli chodzi o eloquent ORM, ma te same metody typu orWhere i tak dalej:

Artisan::command('get-by-name {name}', function (string $name) {

    $people = Person::where('firstName', $name)
    ->orWhere('lastName', $name)
    ->get();

    foreach($people as $person){
        $this->comment("Name: {$person->firstName} {$person->lastName}");
        $this->comment("Age: {$person->age}");
        $this->comment("Created at: {$person->created_at}");
    }
    
});

Natomiast musimy pamiętać, że builder query buildera i eloquenta to dwie różne rzeczy:

use Illuminate\Database\Query\Builder; <--- QUERY BUILDER
use Illuminate\Database\Eloquent\Builder; <--- eloquent ORM

Ok, na tym na razie zakończmy.