Laravel + Eloquentでreliese/laravelを用いてモデルクラスをScaffoldingする

# Laravel + EloquentでモデルのScaffoldingを行う

以前Symfonyを触っていたとき、モデルをScaffoldingして作っていたんですが、
Laravelの場合はどうするんだろう、って思って調べました。
[reliese/laravel](https://packagist.org/packages/reliese/laravel) を使います。
サクッと作れて便利！

## 環境

|名前|バージョン|
|---| -------- |
|PHP | 7.1.8    |
|Laravel| 5.5.5 |
|reliese/laravel | 0.0.13 |

## 手順

composer経由でdevでインストールします。

```
$ composer require --dev reliese/laravel
```

インストールした後はartisan経由で使用するのでサービスプロバイダに登録します。
app/Providers/AppServiceProvider.php を修正します。
registerに環境がlocalの場合のみ読み込むように設定します。

```app/Providers/AppServiceProvider.php
public function register()
{
    if ($this->app->environment() == 'local') {
        $this->app->register(\Reliese\Coders\CodersServiceProvider::class);
    }
}
```

これでartisanから呼び出せるようになります。
scaffoldingの設定ファイルを作成します。

```
$ php artisan vendor:publish --tag=reliese-models
$ php artisan config:clear
```

これでScaffoldingの設定ファイルconfig/models.phpが生成されます。
デフォルトのままでもScaffoldingはできるのでまずはこのままでScaffoldingします。

```
$ php artisan code:models
```

これでデフォルトDBのスキーマから全てのモデルを自動でapp/Modelsに生成します。
ちなみにテーブルを指定する場合は

```
$ php artisan code:models --table=users
```

で指定することができます。

さて、テーブルスキーマが、

```
mysql> desc users;
+-----------------+---------------------+------+-----+---------+----------------+
| Field           | Type                | Null | Key | Default | Extra          |
+-----------------+---------------------+------+-----+---------+----------------+
| id              | int(10) unsigned    | NO   | PRI | NULL    | auto_increment |
| email           | varchar(255)        | NO   | UNI | NULL    |                |
| password        | varchar(255)        | NO   |     | NULL    |                |
| remember_token  | varchar(100)        | YES  |     | NULL    |                |
| user_type       | tinyint(3) unsigned | NO   |     | NULL    |                |
| created_at      | timestamp           | YES  |     | NULL    |                |
| updated_at      | timestamp           | YES  |     | NULL    |                |
| expiration_at   | timestamp           | YES  |     | NULL    |                |
| deleted_at      | timestamp           | YES  |     | NULL    |                |
+-----------------+---------------------+------+-----+---------+----------------+

mysql> desc user_action_logs;
+--------------------+------------------+------+-----+---------+----------------+
| Field              | Type             | Null | Key | Default | Extra          |
+--------------------+------------------+------+-----+---------+----------------+
| id                 | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| user_id            | int(10) unsigned | NO   | MUL | NULL    |                |
| action_type        | tinyint(4)       | NO   |     | NULL    |                |
| url                | varchar(255)     | NO   |     | NULL    |                |
| created_at         | timestamp        | YES  |     | NULL    |                |
| updated_at         | timestamp        | YES  |     | NULL    |                |
+--------------------+------------------+------+-----+---------+----------------+
```

というようなusersテーブルにuser_action_logsがuser_idで紐づく場合は
以下の内容でモデルクラスが自動生成されます。

```app/Models/User.php
<?php

/**
 * Created by Reliese Model.
 * Date: Thu, 21 Sep 2017 22:08:23 +0900.
 */

namespace App\Models;

use Reliese\Database\Eloquent\Model as Eloquent;

/**
 * Class User
 *
 * @property int $id
 * @property string $email
 * @property string $password
 * @property string $remember_token
 * @property int $user_type
 * @property \Carbon\Carbon $created_at
 * @property \Carbon\Carbon $updated_at
 * @property \Carbon\Carbon $expiration_at
 * @property string $deleted_at
 *
 * @property \Illuminate\Database\Eloquent\Collection $user_action_logs
 *
 * @package App\Models
 */
class User extends Eloquent
{
	use \Illuminate\Database\Eloquent\SoftDeletes;

	protected $casts = [
		'user_type' => 'int'
	];

	protected $dates = [
		'expiration_at'
	];

	protected $hidden = [
		'password',
		'remember_token'
	];

	protected $fillable = [
		'email',
		'password',
		'remember_token',
		'expiration_at',
		'user_type'
	];

	public function user_action_logs()
	{
		return $this->hasMany(\App\Models\UserActionLog::class);
	}
}
```

* 論理削除の場合は（deleted_atがあれば）SoftDeletesをuseする
* $castの設定
* $datesの設定
* $hiddenの設定
* $fillableの設定
* リレーションの設定

がスキーマの特性によって設定されます。
usersは親になるのでhasManyでUserActionLogを持つ設定がされています。

ちなみに子のモデルは

```app/Models/UserActionLog.php
<?php

/**
 * Created by Reliese Model.
 * Date: Thu, 21 Sep 2017 22:08:23 +0900.
 */

namespace App\Models;

use Reliese\Database\Eloquent\Model as Eloquent;

/**
 * Class UserActionLog
 *
 * @property int $id
 * @property int $user_id
 * @property int $action_type
 * @property string $url
 * @property \Carbon\Carbon $created_at
 * @property \Carbon\Carbon $updated_at
 *
 * @property \App\Models\User $user
 *
 * @package App\Models
 */
class UserActionLog extends Eloquent
{
	protected $casts = [
		'user_id' => 'int',
		'action_type' => 'int'
	];

	protected $fillable = [
		'user_id',
		'action_type',
		'url'
	];

	public function user()
	{
		return $this->belongsTo(\App\Models\User::class);
	}
}
```

の内容で生成されます。
こちらはbelogsToが設定されて親のモデルはUserとなっています。
このように簡単にモデルクラスをScaffoldingできますね。便利！

## config/models.phpの設定

出力するモデルのディレクトリを変更したい場合や、
生成するクラスの名前空間を変更したい場合、
extendsするクラスはEloquentにしたいとか、
テーブルによっては自動生成の対象としたくない
などがあると思います。

それぞれconfig/models.phpの該当する項目を変更することで対応できます。

### 出力するモデルのディレクトリを変更したい

```config/models.php
'path' => app_path('Models/Eloquent'),
```

app/Models/Eloquent配下に生成されるようにします。

### 生成するクラスの名前空間を変更したい場合

```config/models.php
'namespace' => 'Common\Models\Eloquent',
```

生成されるクラスの名前空間が

```php
namespace Common\Models\Eloquent;
```

になります。

### extendsするクラスはEloquentのクラスを使いたい

```config/models.php
'parent' => Illuminate\Database\Eloquent\Model::class,
```

と指定すると

```php
use Illuminate\Database\Eloquent\Model as Eloquent;
```

と生成されます。
自動生成されるclassではEloquentエイリアスをextendsしているので、エイリアスの本体が変わることによってIlluminate\Database\Eloquent\Modelをextendsされるようになります。

ちなみにデフォルトだと

```php
use Reliese\Database\Eloquent\Model as Eloquent;
```

で生成されます。

### 自動生成の対象としない

```config/models.php
'except' => [
    'migrations', 'users',
],
```

exceptの配列に含めればOK。
この場合migrationsテーブルとusersテーブルは自動生成の対象となりません。

## まとめ

以上でLaravel + EloquentでモデルをScaffoldingする場合の手順になります！
けっこう便利！