Laravelチュートリアル4 -データベースを使用して処理を書いてみよう

Laravel

Laravelでデータベースを使用して開発をする

本章では、いよいよLaravelでデータベースを使用した開発方法を学習していきましょう!

Web系の開発でよく使用するデータベースには、MySQL, PostgreSQL, Oracle, SQLiteなどがあります。

みなさんもプログラミングを勉強していればいくつか耳にしたことがあるはずです。

それぞれのデータベースの特徴などの説明は割愛いたしますが、今回は一番導入が簡単なSQLiteを使用して、Laravelの学習を始めていきましょう!

SQLiteはファイルを作成するだけで簡単に使用を開始できるため、今回は学習目的で使用していきます。

マイグレーションまで実施してみよう!

Laravelでは初期インストール時からいくつかテーブルを生成するためのファイル(マイグレーションファイル)が用意されています。

まずは試しにこのマイグレーションファイルからテーブルを生成(マイグレーション)してみましょう!

マイグレーションファイルを元にしてテーブルを生成することをマイグレーションと言います。

SQLiteでマイグレーションを実施する手順は、こちらの記事に詳しくまとめておきました。

まずは、ちゃんとマイグレーションまでうまくいくか試してみてください!

テーブルを作成してみよう!

前項までにmigrateコマンドを使用して、マイグレーションが実行できるところまでを確認できました。

まだ今の段階では、マイグレーションが何をしているのかも理解できていないと思います。

これから実際に自分でマイグレーションファイルを作成して、マイグレーションを実施し、裏でどんなことが起こっているか理解できるようにしていきましょう!

マイグレーションファイルを作成する

それでは、テーブルを作成するためにマイグレーションファイルを作っていきましょう!

今回は仮にペットを管理する目的があるとして、ペットテーブルを作成してみます!

まずはコマンドからマイグレーションファイルの雛形を生成しましょう!

php artisan make:migration create_pets_table --create=pets

こんな感じで以下のパスにマイグレーションファイルが作成されていればOKです。

database/migrations/2019_06_05_184203_create_pets_table.php

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePetsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('pets', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('pets');
    }
}

マイグレーションファイルを修正する

今回は、テーブルにペットの名前、生年月日、性別を表すカラムを作成してみましょう!

以下のようにマイグレーションファイルを修正してください。

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePetsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('pets', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('birthday');
            $table->string('gender');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('pets');
    }
}

マイグレーションを実行する

それでは作成したマイグレーションファイルを元にマイグレーションを実行しましょう!

$ php artisan migrate

実行結果

Migrating: 2019_06_05_184203_create_pets_table
Migrated:  2019_06_05_184203_create_pets_table

これでマイグレーションが実行されて、petsテーブルが作成されます。

でもコマンドを実行しただけで、ちゃんとテーブルが作成されたのか実感が湧きませんよね?

次項で実際にデータベース覗いてみて、ちゃんとテーブルが作成されているかを見てみましょう!

実際に作成されたテーブルを見てみよう!

それでは、実際にSQLiteのコマンドラインを使用して、実際のデータベースの中を除いてみましょう

SQLiteのインストール

まずSQLiteのデータベースを操作するには、SQLiteのインストールが必要です。

以下の手順に沿ってインストールをしていきましょう!

Windowsの場合

Windowsの場合の手順はこちらを参考にしてください!

上記のサイトのSQLiteコマンドラインプログラムの配置までできたら、本チュートリアルに戻ってきて引き続き以下の確認を行って下さい。

SQLiteのコマンド群を環境変数PATHへ追加する

上記のサイトの手順で、SQLiteのコマンドラインプログラムを配置しただけだと、まだコマンドとしてSQLiteが使用できない状態であると思いますので、環境変数PATHへ追加する必要があります。

sqlite3.exeがあるディレクトリを環境変数PATHへ追加してください!

環境変数へ追加後、ターミナルまたはコマンドプロンプトで以下のコマンドを実行して、バージョンが表示されればSQLiteのインストール完了です!

sqlite3 --version

データベースに接続してみる

SQLiteのコマンドが使用できるようになったら、さっそくデータベースへ接続してみましょう!

まずターミナルまたはコマンドプロンプトでLaravelプロジェクトディレクトリまで移動しましょう!

そこで以下のコマンドを実行するとデータベースへ接続することができます。

sqlite3 database/database.sqlite 

実行結果

SQLite version 3.26.0 2018-12-01 12:34:55
Enter ".help" for usage hints.
sqlite> 

こんな感じで、SQLiteのバージョンが表示されてsqlite>でプロンプトが返ってくればOKです。

テーブルを確認する

データベースへ接続ができたら、まずは以下のコマンドで、現在存在しているテーブルを確認してみましょう!

sqlite> .table

実行結果

migrations       password_resets  pets             users    

上記の実行結果より、現在のデータベースには

  • migrationsテーブル
  • password_resetsテーブル
  • petsテーブル
  • usersテーブル

が存在していることがわかりますね!

マイグレーションを実行するの手順で、作成したpetsテーブルもちゃんと作成されていることがわかります!

テーブル定義を確認する

次は作成したpetsテーブルテーブル定義を確認してみましょう!

sqlite> .schema pets

実行結果

CREATE TABLE IF NOT EXISTS "pets" ("id" integer not null primary key autoincrement, "name" varchar not null, "birthday" varchar not null, "gender" varchar not null, "created_at" datetime null, "updated_at" datetime null);

ちゃんとテーブル定義が出力されましたが、ちょっとこれだと見にくいですね。

見やすく整形したものがこちらです。

CREATE TABLE IF NOT EXISTS "pets" (
    "id" integer not null primary key autoincrement,
    "name" varchar not null, "birthday" varchar not null,
    "gender" varchar not null,
    "created_at" datetime null,
    "updated_at" datetime null
);

マイグレーションファイルを修正するでマイグレーションファイルに指定した通り、id, name, birthday, genderカラムがちゃんと定義されていることがわかりますね!

created_atupdated_atカラムは、マイグレーションファイルでtimestamps()を指定することで定義されるようになります。

ここらへんの細かいところは後々理解していけば良いのですが、一応今ざっと確認しておきたい人のために該当の公式サイトのリンクを貼っておきますね!

データをinsertしてみる

petsテーブルにデータを挿入してみましょう!

テーブルへのデータの挿入は、SQLinsert文を使用します。

insert文でデータを挿入するときの書式は以下です。

insert文の書式

INSERT INTO テーブル名(カラム名1, カラム名2, ...) values(データ1, データ2, ...);

実行するinsert文の例

以下のinsert文を実際に実行してみて、petsテーブルにデータを挿入してください!

試しにpochiという名前のペットデータを挿入しています。

sqlite> INSERT INTO pets(name, birthday, gender, created_at, updated_at) values("pochi", "2015/06/06", "male", datetime('now', 'localtime'), datetime('now', 'localtime'));

データをselectしてみる

petsテーブルに挿入したデータを確認してみましょう!

テーブル内のデータの表示は、SQLselect文を使用します。

select文でデータを表示するときの書式は以下です。

select文の書式

# カラム名を指定して取得する場合
sqlite> select カラム名1, カラム名2 from テーブル名;

# 全取得する場合
sqlite> select * from テーブル名;

実行するselect文の例

以下のselect文を実際に実行してみて、petsテーブル内にあるデータを表示してみましょう!

sqlite> select * from pets;

実行結果

先程挿入したpochiのデータがちゃんと表示されていることがわかりますね!

1|pochi|2015/06/06|male|2019-06-06 04:21:03|2019-06-06 04:21:03

モデルを作成しよう

ここまでで、実際にSQLiteのコマンドを使用して、データの挿入や表示ができるようになりました!

今度はLaravelからデータベース内のデータを操作できるように学習していきましょう!

Laravelでは、EloquentというORMを使用してデータベースへアクセスすることで、先程SQLで行ったようなテーブルの操作をPHPのメソッドとして実行できるようになります。

モデル作成コマンドの書式

php artisan make:model モデル名

実行するモデル作成コマンドの例

以下のコマンドを実行して、モデルを作成しましょう!

php artisan make:model Pet

以下のモデルのファイルが作成されます。

app/Pet.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Pet extends Model
{
    //
}

今回は生成したデフォルトの状態でモデルを使用するため、作成したモデルはこのまま使っていきます。

ORMを利用してDBを抽象化して扱うことで、裏で使われているデータベースがSQLiteやMySQL、PostgreSQLなど、どれを使用していてもLaravelからは同じ操作でテーブルの操作をすることができるようになります。

Eloquentについてのより詳しい説明はこちらを参照ください。

単一データを取得する処理を書いてみよう!

それでは、Laravelでデータを取得する操作を書いてみましょう!

ルーティング

まずは、ルーティングを設定します。

routes/web.php

Route::get('/select', 'SampleController@select');

コントローラー

データベースから特定のIDを持つデータを取得するのに必要な手順は以下です。

  • use App\Pet; で先程作成したモデルをuseする
  • Pet::find(1); で、idが1のデータを取得する

app/Http/Controllers/SampleController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Pet;

class SampleController extends Controller
{
    public function index()
    {
        .
        .
    }

    public function select()
    {
        $pochi = Pet::find(1);

        return view('select', [
            "pochi" => $pochi
        ]);
    }

}

Laravelで、Pet::find(1);を実行すると裏では、以下のSQLが流れています。
select * from “pets” where “pets”.”id” = 1 limit 1

ビュー

取得した結果を画面に表示するためにビューを追加しましょう!

resources/views/select.blade.php

<h2>Pochi</h2>

<table border="1">
    <tr>
        <th>名前</th>
        <th>生年月日</th>
        <th>性別</th>
    </tr>
    <tr>
        <td>{{$pochi->name}}</td>
        <td>{{$pochi->birthday}}</td>
        <td>{{$pochi->gender}}</td>
    </tr>
</table>

表示結果

http://127.0.0.1:8000/selectへアクセスすると、SQLiteのコマンドラインから挿入したpochiのデータが表示されているかと思います!

複数データを取得する処理を書いてみよう!

続いて、Laravelで複数データを取得する方法を学習していきます。

ルーティング

まずはルーティングを追加します。

routes/web.php

Route::get('/select_many', 'SampleController@selectMany');

コントローラー

今度は、ペットテーブル内のデータをPet::orderBy(‘id’, ‘asc’)idの昇順でデータをソートして、->get()全データを取得しています。

app/Http/Controllers/SampleController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Pet;

class SampleController extends Controller
{
    public function index()
    {
        .
        .
    }

    public function select()
    {
        .
        .
    }

    public function selectMany()
    {
        $pets = Pet::orderBy('id', 'asc')->get();

        return view('select_many', [
            "pets" => $pets
        ]);
    }

}

Laravelで、Pet::orderBy(‘id’, ‘asc’)->get();を実行すると裏では、以下のSQLが流れています。
select * from “pets” order by “id” asc

ビュー

取得した結果を表示するためにビューを追加します。

今回は複数のレコードが取得されるため、ブレードのforeachを使用することでループして複数データを表示しています。

resources/views/select_many.blade.php

<h2>Pet List</h2>

<table border="1">
    <tr>
        <th>名前</th>
        <th>生年月日</th>
        <th>性別</th>
    </tr>
    @foreach($pets as $pet)
    <tr>
        <td>{{$pet->name}}</td>
        <td>{{$pet->birthday}}</td>
        <td>{{$pet->gender}}</td>
    </tr>
    @endforeach
</table>

表示結果

http://127.0.0.1:8000/select_manyへアクセスすると、1件のみデータが表示されると思います。

ペットテーブルには1件しかデータを挿入していないためですね!

これだとデータが1件しか表示されず、foreachでループさせた意味がないので、再度SQLiteのコマンドラインを使用して、いくつかデータを追加してみましょう!

データの追加

# データベースへ接続
$ sqlite3 database/database.sqlite 

# データの追加
sqlite> INSERT INTO pets(name, birthday, gender, created_at, updated_at) values("koro", "2019/06/06", "male", datetime('now', 'localtime'), datetime('now', 'localtime'));

# データの追加
sqlite> INSERT INTO pets(name, birthday, gender, created_at, updated_at) values("yume", "2014/06/06", "female", datetime('now', 'localtime'), datetime('now', 'localtime'));

表示結果2

再度http://127.0.0.1:8000/select_manyへアクセスすると、SQLiteのコマンドラインから挿入したpochiやkoro、yumeなどの複数のデータが表示できていることがわかりますね!

データを挿入する処理を書いてみよう!

今度はLaravelでデータを挿入する方法を学習していきます。

ルーティング

まずはルーティングを追加します。

routes/web.php

Route::get('/insert', 'SampleController@insert');

コントローラー

以下のinsert()メソッドの処理を追加してください。

$pet = new Pet();でペットモデルのインスタンスを取得して、$pet->name = “shiro”;のようにすることで各要素に挿入する値を埋めていきます。

最後にsave()することでデータがDBへ保存されるため、忘れずにsave()を実行してくださいね!

app/Http/Controllers/SampleController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Pet;

class SampleController extends Controller
{



    public function select()
    {
        .
        .
    }

    public function insert()
    {
        $pet = new Pet();

        $pet->name = "shiro";
        $pet->birthday = "1980/06/16";
        $pet->gender = "female";

        $pet->save();

        return "データを挿入しました";
    }

}

Laravelでは、DBへデータを保存する方法はいくつかありますが、今回はこの一番手軽な方法で学習を進めていきます。

その他のDBへのデータ挿入(保存)方法を学びたい方は公式サイトを見てみてくださいね!

表示結果

http://127.0.0.1:8000/insertへアクセスすると、以下のようにデータを挿入しましたと表示されると思います。

今回は、ビュー(HTML)は作成しませんでしたが、コントローラーでreturn “データを挿入しました”;として、文字列を返しています。

これで、データが一件、挿入されました。

http://127.0.0.1:8000/select_manyへアクセスしてみましょう!

shiroのデータがちゃんと表示されていますね!

ちなみに、今の段階だと/insertのURLへ何回もアクセスすると、同じshiroのデータがたくさん入っちゃいます!!

ちょっと変なのでこちらは今後任意のデータを挿入できるように直していきましょうね!

データを削除する処理を書いてみよう!

今度はLaravelでデータを削除する処理を学習していきます。

ルーティング

まずはルーティングを追加します。

routes/web.php

Route::get('/delete', 'SampleController@delete');

コントローラー

以下のdelete()メソッドの処理を追加してください。

Pet::orderBy(‘id’, ‘asc’)までの部分でpetsテーブルにあるデータをidの昇順にします。

続いて、->first()の部分で、ソートされたデータうち一番最初のデータ(モデルオブジェクト)を取得します。

これを最後に->delete();とすることで削除することができるのです!

app/Http/Controllers/SampleController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Pet;

class SampleController extends Controller
{


    public function insert()
    {
        .
        .
    }

    public function delete()
    {
        Pet::orderBy('id', 'asc')->first()->delete();

        return "データを削除しました";
    }

}

表示結果

http://127.0.0.1:8000/deleteへアクセスすると、以下のようにデータを削除しました
と表示されると思います。

これで一覧の先頭のデータが削除されています。

ちなみに、こちらも/deleteのURLへ何回もアクセスすると、一覧の上から順番にバンバンデータ消されていくので試してみてくださいね!

削除する対象のデータがなくなるとLaravelのエラー画面が表示されますが、焦らないで下さい!

その時は、再度/insertのURLにアクセスして、データを入れてみましょう!

データを更新する処理を書いてみよう!

それでは最後にLaravelでデータを更新する処理を学習していきます。

ルーティング

まずはルーティングを追加します。

routes/web.php

Route::get('/update', 'SampleController@update');

コントローラー

以下のupdate()メソッドの処理を追加してください。

Pet::orderBy(‘id’, ‘asc’)->first()までは、先程のdelete()メソッドと同じで、petsテーブルにあるデータのidの昇順で一番最初のデータを取得しています。

続いて、update([‘name’ => “jonny”])の部分で、nameの値を“jonny”へ更新しています。

app/Http/Controllers/SampleController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Pet;

class SampleController extends Controller
{


    public function delete()
    {
        .
        .
    }

    public function update()
    {
        Pet::orderBy('id', 'asc')->first()->update(['name' => "jonny"]);

        return "データを更新しました";
    }

}

モデル

このままだと、Petテーブルの値が更新できないので、モデルへ設定が必要となります。

以下のように、protected $guarded = [‘id’];の一行を追加してください。

app/Pet.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Pet extends Model
{
    protected $guarded = ['id'];
}

今の段階では値の更新をする場合はルールとして$guardedを設定する必要があると覚えておけば良いでしょう。

気になる方は、公式サイト僕がLaravelのEloquentに$fillableでなく$guardedを指定する理由 – Qiitaを見てみると参考になります。

表示結果

http://127.0.0.1:8000/updateへアクセスすると、以下のようにデータを更新しましたと表示されると思います。

このように、一覧の先頭のデータの名前が“jonny”へ更新されていることがわかりますね!

まとめ

いかがでしたでしょうか?

これで一通りのデータベースの処理が学習できました!

ただこれだと、Webの画面上から操作して任意でデータを操作できないので、システムとしては使いものにならないですよね!

次のチュートリアルでは実際にHTMLのフォームから値を受け取って、データを更新していく方法を学習していきましょう!

筆者オススメの関連商品

コメント