[ Laravel ] Migration-> Seed -> DB Connection -> View

Laravelを使う機会がきたので、実装しながら理解した経緯を記す。


# ◆ 今日やること

MySQLにデータベースを作成し、テーブルを作成、データを入れて、LaravelでCRUD操作をできるようにしたい

- Migrationでテーブル作成
    - [Database: Migrations \- Laravel \- The PHP Framework For Web Artisans](https://laravel.com/docs/5.3/migrations)
- Seedingでテストデータ挿入
    - [Database: Seeding \- Laravel \- The PHP Framework For Web Artisans](https://laravel.com/docs/5.3/seeding)
- MySQLへ接続
    - [Database: Getting Started \- Laravel \- The PHP Framework For Web Artisans](https://laravel.com/docs/5.3/database
- Route、Controller、Model、Viewの実装
    - [Routing \- Laravel \- The PHP Framework For Web Artisans](https://laravel.com/docs/5.3/routing)
    - [Controllers \- Laravel \- The PHP Framework For Web Artisans](https://laravel.com/docs/5.3/controllers)
    - [Blade Templates \- Laravel \- The PHP Framework For Web Artisans](https://laravel.com/docs/5.3/blade)
    - Modelがない？
        - 意図的にModelディレクトリは作っていない。
        - Eloquent models をデフォルトではappディレクトリに配置するようにしているが、開発者が好きなようにしてくださいとのこと

# ◆ バージョン

```bash
 $ php artisan --version
Laravel Framework version 5.3.28

 $ php --version
PHP 7.1.0 (cli) (built: Dec  2 2016 03:30:24) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies

```

# ◆ 実装編

##  Migrationでテーブル作成

- Migrationファイルを作成します{}は自分が作成するテーブル名で。今回は「composers」テーブルを作成します。

```bash
$ php artisan make:migration {create_composers_table}

Created Migration: 2017_01_04_143404_create_composers_table
```

### > migration/yyyy_mm_dd_XXXXXX_create_composers_table.php

-　「php artisan make:migration {}」を実行すると、上記のファイルが作成されます

```php

<?php

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

class CreateComposersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        //
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        //
    }
}
```

### > migration/yyyy_mm_dd_XXXXXX_create_composers_table.php

- 新しい「composers」テーブルを作成するのに、facedeのShemaメソッドを使います。

```php
<?php

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

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

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

```

### > migrateの実行

```php
$ php artisan migrate
Migration table created successfully.
Migrated: 2017_01_04_143404_create_composers_table
```
MySQLでテーブルができているか確認します

```mysql
mysql> desc composers;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255)     | NO   |     | NULL    |                |
| en_name    | varchar(255)     | NO   |     | NULL    |                |
| created_at | timestamp        | YES  |     | NULL    |                |
| updated_at | timestamp        | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
```


## Seedingでテストデータ挿入

seedクラスを使うことで、初期データの投入をすることができます。

fakerはテストデータを作るのにとっても便利です。
- [fzaninotto/Faker: Faker is a PHP library that generates fake data for you](https://github.com/fzaninotto/Faker)


### > factories/ComposerFactory.php

- fackerを使ってテストデータを入れます
- factoryクラスを使うことでより効率的になります。
    - [Database Testing \- Laravel \- The PHP Framework For Web Artisans](https://laravel.com/docs/5.3/database-testing#writing-factories)


```php

<?php

/*
|--------------------------------------------------------------------------
| Composer Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/

$factory->define(App\Composer::class, function (Faker\Generator $faker) {

    return [
        'name' => $faker->name,
        'en_name' => $faker->text,
        'created_at' => $faker->date,
        'updated_at' => $faker->date
    ];
});

```

### > seeds/ComposersTableSeeder.php

作成したfactoryクラスを使ってデータを50件ほど登録させるようにします

```php
<?php

use Illuminate\Database\Seeder;

class ComposersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // Sample 1
        // DB::table('composers')->insert([
        //     'name' => str_random(10),
        //     'en_name' => 'Taro Yamada'
        // ]);

        factory(App\Composer::class, 50)->create();

    }
}
```



### > seeds/DatabaseSeeder.php

上記のSeederクラスを実行させます

```php
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call(ComposersTableSeeder::class);
    }
}

```

### > seedの実行

```
php artisan db:seed
```



## MySQLへ接続

今回は、MySQLを使います。
### > .env

このファイルに環境依存の定義を書いておきます。

```
DB_CONNECTION=mysql
DB_READ_HOST=127.0.0.1
DB_WRITE_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=databasename
DB_USERNAME=username
DB_PASSWORD=password
```


### > config/database.php


- レプリケーションをした時のためにReadとWriteを分けておく。

- envについて
    - 第一引数は.envから取得したいキー名
    - 第二引数は、デフォルト値

```php
    'connections' => [

        'mysql' => [
            'read' => [
                'host' => env('DB_READ_HOST', 'localhost'),
                ],
            'write' => [
                'host' => env('DB_WRITE_HOST', 'localhost')
            ],
            'driver' => 'mysql',
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'database'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', 'pass'),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ]
```


## Route、Controller、Model、Viewの実装

今回使った最小限のファイル

```
├── app
│   ├── Composer.php （-> Model）
│   ├── Http
│   │   ├── Controllers
│   │   │   ├── ComposersController.php（-> Controller）
├── bootstrap
│   ├── app.php
├── config
│   ├── app.php
│   ├── database.php
├── database
│   ├── factories
│   │   ├── ComposerFactory.php（-> Factory）
│   ├── migrations
│   │   └── 2017_01_04_143404_create_composers_table.php（-> Migration）
│   └── seeds
│       ├── ComposersTableSeeder.php（-> Seeder）
│       └── DatabaseSeeder.php
├── resources
│   └── views
│       ├── composers
│       │   └── list.blade.php（-> Template）
├── routes
│   └── web.php（-> Route）
```

### > routes/web.php

```php
/*
|--------------------------------------------------------------------------
| Public routes
|--------------------------------------------------------------------------
*/
Route::get('/composers/list', 'ComposersController@list')->name('composers.list');
```

### > Http/Controllers/ComposersController.php

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;

use App\Composer;

class ComposersController extends Controller
{
    protected $composers;


    function __construct(Composer $composers)
    {
        $this->composers = $composers;
    }


    /**
     * Show a list of all of the application's users.
     *
     * @return Response
     */
    public function list()
    {
        $result = $this->composers->getComposers();
        return view('composers.list', ['composers' => $result]);
    }
}
```

### > app/Composer.php


```php
<?php

namespace App;
use Illuminate\Database\Eloquent\Model;

class Composer extends Model
{


    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'composers';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['id', 'name', 'en_name'];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['created_at', 'updated_at'];


    public function getComposers()
    {
        $query = $this;
        return $query->paginate(20);
    }


}
```


### > resources/views/composers/list.blade.php


```php
<div class="page-header">
<h3>Composers List</h3>
</div>

@foreach ($composers as $composer)
    <p>This is composer {{ $composer->name }} ::: {{ $composer->en_name}}}</p>
@endforeach
```