JavaScriptを有効にしてください

【Laravel】使用していないModel, DBのテーブルを特定するコマンドを自作

 ·  ☕ 2 分で読めます

【Laravel】使用していないModel, DBのテーブルを特定するコマンドを自作

Laravelで使用していないModel, DBのテーブルを特定するコマンドを自作しました。
リファクタの時に役立ちます!

確認環境

Laravel 5-9 の環境で確認をしております。

コマンド作成

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;

class UnuseTable extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:UnuseTable';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Laravel Model Not Exists Table';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $files = $this->getFileList(app_path('Model'));
        $modelFiles = array_map(
            function ($value) {
                // ファイルパスから base_path を削除
                $value = str_replace(base_path() . '/', '', $value);
                // 拡張子を削除
                $filepath = pathinfo($value);
                $value = $filepath['dirname'] . '/' . $filepath['filename'];

                // ファイルパスを namespace に修正
                $value = str_replace('app/', 'App/', $value);
                $value = str_replace('/', '\\', $value);
                return $value;
            },
            $files
        );

        // ModelからTable名を取得
        $modelTables = [];
        foreach ($modelFiles as $value) {
            $model = app()->make($value);
            $modelTables[] = $model->getTable();
        }

        // DBからテーブルを取得
        $dbTables = DB::select('show tables;');
        $dbTables = array_reduce(
            array_map(function ($table) {
                return array_values((array) $table);
            }, $dbTables),
            'array_merge',
            []
        );

        // DBとModelの差分を取得
        $modelOnlys = array_diff($modelTables, $dbTables);
        $dbOnlys = array_diff($dbTables, $modelTables);

        $this->info('##################################################');
        $this->info('Laravel Model Use Table');
        if (count($modelTables) == 0) {
            $this->info('Nothing!!');
        } else {
            $this->info('Count:' . count($modelTables));
        }
        foreach ($modelTables as $model) {
            $this->comment($model);
        }
        $this->info('');

        $this->info('##################################################');
        $this->info('Laravel Model Only');
        if (count($modelOnlys) == 0) {
            $this->info('Nothing!!');
        } else {
            $this->info('Count:' . count($modelOnlys));
        }
        foreach ($modelOnlys as $model) {
            $this->comment($model);
        }
        $this->info('');
        $this->info('##################################################');
        $this->info('Laravel Model Not Exists Tables');
        if (count($dbOnlys) == 0) {
            $this->info('Nothing!!');
        } else {
            $this->info('Count:' . count($dbOnlys));
        }
        foreach ($dbOnlys as $table) {
            $this->comment($table);
        }
        $this->info('##################################################');
    }

    private function getFileList($dir)
    {
        $iterator = new RecursiveDirectoryIterator($dir);
        $iterator = new RecursiveIteratorIterator($iterator);
        $list = array();
        foreach ($iterator as $fileinfo) {
            if ($fileinfo->isFile()) {
                $list[] = $fileinfo->getPathname();
            }
        }
        return $list;
    }
}

実行

実際に実行してみます。

php artisan command:UnuseRoute

実行すると下記のようにLaravelのModelにしかないものとLaravelのModelにないTableが出力されます。

##################################################
Laravel Model Use Table
Count:1
sample

##################################################
Laravel Model Only
Nothing!!

##################################################
Laravel Model Not Exists Tables
Count:1
sample_bk
##################################################

これでLaravelでは使用していないテーブルを特定することが可能です。

共有

こぴぺたん
著者
こぴぺたん
Copy & Paste Engineer