# laravel 資料庫 Seeder 練習 @ver 0.1.2 @date 2019-03-20 21:24:27 (星期三) @ver 0.1.1 @date 2019-03-18 10:37:11 (星期一) [seeding 參考(繁體中文 資料庫 : 資料填充)](https://docs.laravel-dojo.com/laravel/5.5/seeding) [seeding 參考(簡體中文 数据填充)](https://learnku.com/docs/laravel/5.8/seeding) 999. ## Seeder 資料庫資料填充 資料庫資料填充, 就是用 artisan 在資料表產生預設數據. 完成了上一節的 Auth 實作, 我們必須進入網頁去實際填寫一些資料, 才能新增一位 User 到資料庫. 有時只是要測試程式邏輯或 Model , 花一些時間作一個 Form 來填寫資料再新增至資料庫, 相當不划算. 還有些狀況是要預設一些值到資料庫裡給後續工作使用, 這時候就需要 Seeder 來幫忙. > 繼續上一個專案 testAuth ### 建立 Seeder Class Seeder 程式要自行建立, 會放到 `database/seeds/` 目錄下 #### 命令 ```bash php artisan make:seeder UsersTableSeeder git st -s ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ php artisan make:seeder UsersTableSeeder Seeder created successfully. [alex@nvda ~/jobs/testAuth ]$ git st -s ?? database/seeds/UsersTableSeeder.php [alex@nvda ~/jobs/testAuth ]$ ``` 直接產生一個 `database/seeds/UsersTableSeeder.php` 檔案, 編輯這個檔案, 在 run() 函數裡加上要產生的 user 欄位資料, 可以只寫必填資料. 我使用 DB:: 跟 Factory() 兩種方式產生. #### UsersTableSeeder.php 程式碼 ```php public function run() { // create a demo user DB::table('users')->insert([ 'name' => '測試帳號1', 'email' => 'a@b.com', 'password' => bcrypt('hello'), ]); $user = Factory(App\User::class)->create([ 'name' => '測試帳號2', 'email' => 'b@c.com', // factory default password is 'password' ]); } ``` 原本的 `database/seeds/DatabaseSeeder.php` 檔案, 編輯這個檔案, 在 run() 函數裡加入上面的 Seeder 類別名稱, 用來呼叫產生資料, 若是有多個 Seeder 類別就用陣列. #### DatabaseSeeder.php 程式碼 ```php public function run() { $this->call(UsersTableSeeder::class); // 多個 Seeder 類別就用陣列 // $this->call([UsersTableSeeder::class, ...]); } ``` 完成 Seeder 類別的編寫之後,需要使用 dump-autoload 命令重新產生 Composer 的自動載入程式, 否則會抓不到 UsersTableSeeder 這個 class #### 命令 ```bash composer dump-autoload ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ composer dump-autoload Generating optimized autoload files> Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: beyondcode/laravel-dump-server Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: laravelcollective/html Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Discovered Package: spatie/laravel-permission Package manifest generated successfully. Generated optimized autoload files containing 3552 classes [alex@nvda ~/jobs/testAuth ]$ ``` ### 產生 seed 有好幾種方式可以產生 seed, 只做 seed 或選擇清空資料庫重新建立並 seed, 下列命令請自選一個 #### 命令 ```bash # 全部 seed php artisan db:seed # 或指定某一個資料表 seed php artisan db:seed --class=UsersTableSeeder # 或清空資料庫重新建立並 seed php artisan migrate:fresh --seed ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ php artisan db:seed Seeding: UsersTableSeeder Database seeding completed successfully. [alex@nvda ~/jobs/testAuth ]$ ``` 查看資料表 users, 這 2 筆就程式碼裡的設定, 現在可以進去網頁, 試著用這 2 個 email 登入, 注意他們的密碼不同. #### 執行結果 ```shell mysql> select id,name,email from users; +----+---------------+---------+ | id | name | email | +----+---------------+---------+ | 1 | 測試帳號1 | a@b.com | | 2 | 測試帳號2 | b@c.com | +----+---------------+---------+ 2 rows in set (0.00 sec) ``` ### 工廠大量生產 上面我們用了 `DB::table('users')->insert([...]);` 或 `Factory(App\User::class)->create([...])` 在 seed 時, 自動產生一筆預設的資料, 但萬一, 人生總是會有萬一, 寫程式也是. 需要一次大量產生數百數千筆資料來測試或其他應用時, 此刻就需要工廠來自動化幫我們大量生產假的測試資料, 再度修改 `database/seeds/UsersTableSeeder.php` 檔案, 在原先 run() 函數結束前再加一行 `factory(App\User::class, 6)->create();` 自動產生 6 筆假的測試 users, 如下 #### UsersTableSeeder.php 程式碼 ```php public function run() { // create a demo user DB::table('users')->insert([ 'name' => '測試帳號1', 'email' => 'a@b.com', 'password' => bcrypt('hello'), ]); $user = Factory(App\User::class)->create([ 'name' => '測試帳號2', 'email' => 'b@c.com', // factory default password is 'password' ]); // 原先 run() 函數結束前再加一行 factory() 自動產生 6 筆 users factory(App\User::class, 6)->create(); } ``` 工廠程式也要對照加上我們要讓它大量生產假資料的欄位值, 先加入 `name, email, email_verified_at, password, remember_token` 這幾個欄位 #### database/factories/UserFactory.php 程式碼 ```php use App\User; ... ... ... $factory->define(User::class, function (Faker $faker) { return [ 'name' => $faker->name, 'email' => $faker->unique()->safeEmail, 'email_verified_at' => now(), 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'remember_token' => Str::random(10), ]; }); ``` #### 命令 ```bash php artisan db:seed ``` 出現錯誤訊息 #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ php artisan db:seed Seeding: UsersTableSeeder Illuminate\Database\QueryException : SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'a@b.com' for key 'users_email_unique' (SQL: insert into `users` (`name`, `email`, `password`) values (測試帳號1, a@b.com, $2y$10$6XkZS7tyQCPspaf1B5XjbujI6zmxhpRE.ViZ8bN5sWLzJg5dE7Kdu)) ``` 因為 users 的 email 欄位, 設定為 unique, 所以先前已建立的會衝突, 可以手動去資料庫刪除先前的兩筆, 或直接清空資料庫重新建立並 seed #### 命令 : 清空資料庫重新建立並 seed ```bash php artisan migrate:fresh --seed ``` 查看資料表 users, 會有 8 筆, 前 2 筆是原先的設定, 後 6 筆是用工廠自動化生產的假訊息 #### 執行結果 ```shell mysql> select id,name,email from users; +----+---------------------+-----------------------------------+ | id | name | email | +----+---------------------+-----------------------------------+ | 1 | 測試帳號1 | a@b.com | | 2 | 測試帳號2 | b@c.com | | 3 | Mr. Theron Schumm | jamaal66@example.org | | 4 | Stanton Goldner | gerard21@example.com | | 5 | Lola Effertz Sr. | farrell.aidan@example.com | | 6 | Cary Erdman | heathcote.jacinthe@example.com | | 7 | Mr. Columbus Crooks | pinkie79@example.org | | 8 | Ofelia Lubowitz | rozella.runolfsdottir@example.org | +----+---------------------+-----------------------------------+ 8 rows in set (0.00 sec) mysql> ``` #### git ```bash git add . git commit -m 'laravel 資料庫 Seeder 練習完成 database/seeds/UsersTableSeeder.php' ``` 999. ## 做個 Seeder 小實驗 (bonus) ### git branch 先用 git 開一個 branch , 等會兒做完實驗, 可以返回剛剛的狀態 #### 命令 ```bash git branch git branch -a git branch seeder2 git branch git checkout seeder2 ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ git branch 1 * master [alex@nvda ~/jobs/testAuth ]$ git branch -a 1 * master [alex@nvda ~/jobs/testAuth ]$ git branch seeder2 [alex@nvda ~/jobs/testAuth ]$ git branch 1 * master 2 seeder2 [alex@nvda ~/jobs/testAuth ]$ git checkout seeder2 Switched to branch 'seeder2' [alex@nvda ~/jobs/testAuth ]$ git branch 1 master 2 * seeder2 [alex@nvda ~/jobs/testAuth ]$ [alex@nvda ~/jobs/testAuth ]$ ``` --- [實驗來源參考](https://scotch.io/@wisdomanthoni/make-your-laravel-seeder-using-model-factories) ### 產生 Model 及 Migration 我們需要 `Film(影片), Genre(類型), Comment(評論)` 這三個 `Model` 來做實驗, 執行下列命令後, 產生了 6 個 php 檔案 #### 命令 ```bash php artisan make:model Film -m php artisan make:model Comment -m php artisan make:model Genre -m git st -s ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ php artisan make:model Film -m Model created successfully. Created Migration: 2019_03_20_221753_create_films_table [alex@nvda ~/jobs/testAuth ]$ php artisan make:model Comment -m Model created successfully. Created Migration: 2019_03_20_221825_create_comments_table [alex@nvda ~/jobs/testAuth ]$ php artisan make:model Genre -m Model created successfully. Created Migration: 2019_03_20_221830_create_genres_table [alex@nvda ~/jobs/testAuth ]$ [alex@nvda ~/jobs/testAuth ]$ git st -s ?? app/Comment.php ?? app/Film.php ?? app/Genre.php ?? database/migrations/2019_03_20_221753_create_films_table.php ?? database/migrations/2019_03_20_221825_create_comments_table.php ?? database/migrations/2019_03_20_221830_create_genres_table.php [alex@nvda ~/jobs/testAuth ]$ ``` ### Model 的欄位 > 以下的檔案都在 `/database/migrations/` 目錄下, 而且隨著每個人的建立時間產生不同的檔名, 檔名前段 `年_月_日_時分秒_`, 會用 `___` 省略顯示 增修上面產生 3 個 Model 的欄位, 都在 `public function up()` 裡, 請看程式碼 #### 命令 ```bash vi database/migrations/___create_genres_table.php vi database/migrations/___create_films_table.php vi database/migrations/___create_comments_table.php ``` #### database/migrations/___create_genres_table.php 程式碼 ```php public function up() { Schema::create('genres', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->timestamps(); }); } ``` #### database/migrations/___create_films_table.php 程式碼 ```php public function up() { Schema::create('films', function (Blueprint $table) { $table->bigIncrements('id'); $table->integer('user_id'); $table->string('title'); $table->text('description'); $table->date('release_date'); $table->enum('rating',[ 1, 2, 3, 4, 5] ); $table->integer('genre_id'); $table->string('photo'); $table->string('slug'); $table->timestamps(); }); } ``` #### database/migrations/___create_comments_table.php 程式碼 ```php public function up() { Schema::create('comments', function (Blueprint $table) { $table->bigIncrements('id'); $table->integer('user_id'); $table->integer('film_id'); $table->text('comment'); $table->timestamps(); }); } ``` #### git ```bash git add . ``` ### 產生 Factory 工廠程式碼 #### 命令 ```bash php artisan make:factory GenreFactory --model=Genre php artisan make:factory FilmFactory --model=Film php artisan make:factory CommentFactory --model=Comment ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ php artisan make:factory GenreFactory --model=Genre Factory created successfully. [alex@nvda ~/jobs/testAuth ]$ php artisan make:factory FilmFactory --model=Film Factory created successfully. [alex@nvda ~/jobs/testAuth ]$ php artisan make:factory CommentFactory --model=Comment Factory created successfully. [alex@nvda ~/jobs/testAuth ]$ git st -s ...(前略) ?? database/factories/CommentFactory.php ?? database/factories/FilmFactory.php ?? database/factories/GenreFactory.php [alex@nvda ~/jobs/testAuth ]$ ``` 此時 3 個 `Factory php` 檔案裡 `$factory->define()` 函數是空的, 尚未有任何對應欄位的自動化回傳值. 我們來加一些程式碼, 才能讓工廠運作. #### 命令 ```shell vi database/factories/GenreFactory.php vi database/factories/FilmFactory.php vi database/factories/CommentFactory.php ``` #### database/factories/GenreFactory.php 程式碼 ```php $factory->define(App\Genre::class, function (Faker $faker) { return [ 'name' => $faker->word, // 一個英文字 ]; }); ``` #### database/factories/FilmFactory.php 程式碼 ```php $factory->define(App\Film::class, function (Faker $faker) { return [ 'title' => $faker->sentence(5), // 5 個字以上的句子 'description' => $faker->realText(rand(80, 600)), // 文章 80 ~ 600 字 'release_date' => $faker->date(), 'rating' => rand(1,5), 'genre_id' => function () { // Get random genre id return App\Genre::inRandomOrder()->first()->id; }, 'photo' => 'https://via.placeholder.com/350x150', 'slug' => str_replace('--', '-', strtolower(preg_replace('/[^a-zA-Z0-9]/', '-', trim($faker->sentence(5))))), ]; }); ``` #### database/factories/CommentFactory.php 程式碼 ```php $factory->define(App\Comment::class, function (Faker $faker) { return [ 'comment' => $faker->realText(rand(10, 300)), // 文章 10 ~ 300 字 ]; }); ``` ### 產生 Seeder 類別程式碼 工廠蓋好了, 我們要開始教工廠的員工如何生產我們要的產品(假資料), 這個作業前要先有 Seeder 類別, 這些類別不一定要跟 Model 一一對應, 有可能一對多或多對一, 看實際狀況來實作, 只是這個實驗剛好也用了 3 個 Seeder 類別 #### 命令 ```bash php artisan make:seeder GenreTableSeeder php artisan make:seeder UserFilmSeeder php artisan make:seeder CommentTableSeeder git st -s ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ php artisan make:seeder GenreTableSeeder Seeder created successfully. [alex@nvda ~/jobs/testAuth ]$ php artisan make:seeder UserFilmSeeder Seeder created successfully. [alex@nvda ~/jobs/testAuth ]$ php artisan make:seeder CommentTableSeeder Seeder created successfully. [alex@nvda ~/jobs/testAuth ]$ [alex@nvda ~/jobs/testAuth ]$ git st -s ...(前略) ?? database/seeds/CommentTableSeeder.php ?? database/seeds/GenreTableSeeder.php ?? database/seeds/UserFilmSeeder.php [alex@nvda ~/jobs/testAuth ]$ ``` 完成之後 `database/seeds/` 目錄下會有 3 個新的 `php` 檔, 這一次同時我們要加入一些命令列對話及輸入, 來確定是否真的要執行, 以及執行生產的數量(筆數). 這樣更方便我們隨時可以調整測試, 現在修改剛剛產生出來的工廠生產程式碼. 有點長, 花點時間慢慢消化, 說明就在程式裡. #### database/seeds/GenreTableSeeder.php 程式碼 ```php public function run() { // 要生產多少種 genres (類型) ? 預設值是 10 種 genre (10 筆資料列) $count = (int)$this->command->ask('請問要生產多少種類型 (genres) ?', 10); $this->command->info('工廠生產將會建立 {$count} 筆 genres (類型).'); // 工廠開工生產 $count 筆資料 $genres = factory(App\Genre::class, $count)->create(); $this->command->info('Genres(類型) 生產建立完成!'); } ``` #### database/seeds/UserFilmSeeder.php 程式碼 ```php public function run() { // 要生產多少個 users (用戶) ? 預設值是 8 個 user (10 筆資料列) $userCount = (int)$this->command->ask('請問要生產多少個 users (會員) ?', 8); // 詢問每位 user 要生產 film (影片) 的範圍, 預設值是 0 ~ 10 筆 $r = 0 . '-' . 10; $filmRange = $this->command->ask('請問每位 user 要生產多少支 films (影片) ? 務必要輸入 - 在兩個數字之間, 例如 3-8, 否則會發生錯誤', $r); $this->command->info('工廠生產將會建立 {$userCount} 個 users , 每位 user (會員) 會生產 films (影片) 的範圍為 {$filmRange}.'); // 工廠開工生產 $userCount 筆 user 資料 $users = factory(App\User::class, $userCount)->create(); // 工廠對每位 user 生產 '亂數' 筆 (在下方 count($range) 函數, 亂數產生) films (影片) $users->each(function($user) use ($filmRange){ factory(App\Film::class, $this->count($filmRange)) ->create(['user_id' => $user->id]); }); $this->command->info('Users(會員)及Films(影片) 生產建立完成!'); } // Return random value in given range function count($range) { return rand(...explode('-', $range)); } ``` #### database/seeds/CommentTableSeeder.php 程式碼 ```php public function run() { $r = 5 . '-' . 9; $commentRange = $this->command->ask('請問每支 film (影片) 要生產多少個 comments (評論) ? 務必要輸入 - 在兩個數字之間, 例如 3-8, 否則會發生錯誤', $r); $films = App\Film::all(); $this->command->info('工廠生產將會建立 {$commentRange} 不等的 comments (評論)數, 給 {$films->count()} 支 films (影片).'); // 工廠開工對有限圍的每一 films (影片) 生產 $commentRange (筆數不定) comments 資料 $films->each(function($film) use ($commentRange){ factory(App\Comment::class, $this->count($commentRange)) ->create([ 'film_id' => $film->id, 'user_id' => App\User::all()->random()->id ]); }); $this->command->info('Comments(評論) 生產建立完成!'); } // Return random value in given range function count($range) { return rand(...explode('-', $range)); } ``` ### Seeder 總管 這支程式總管所有 Seeder , 一樣也是修改 `public function run()` 函數成下面的程式碼, 注意, 原本 `$this->call(UsersTableSeeder::class);` 是先前生產時用的, 現在暫時先用 `//` 把它註解不執行, 我們同時也加上確認問句 "是否要清空所有資料表並重新建立" ? #### database/seeds/DatabaseSeeder.php 程式碼 ```php public function run() { // $this->call(UsersTableSeeder::class); // 暫時先不執行 Eloquent::unguard(); // 詢問是否要 Ask for db migration refresh, default is no if ($this->command->confirm('請問在資料填充前, 是否要清空所有資料表並重新建立, 原資料庫會全數刪除 ? Do you wish to refresh migration before seeding, it will clear all old data ?')) { // 直接呼叫 php artisan migrate:fresh $this->command->call('migrate:fresh'); $this->command->line('資料庫資料表清除完成. Database cleared.'); } $this->call([ GenreTableSeeder::class , UserFilmSeeder::class , CommentTableSeeder::class , ]); $this->command->info('資料庫資料填充完成. Database seeded.'); // Re Guard model Eloquent::reguard(); } ``` 萬事俱備, 只欠東風...... ### 資料庫產生 3 個 Model 資料表 上面程式碼的工作都寫好存檔後, 先做一次 migrate 把新增的 3 個 `Film(影片), Comment(評論), Genre(類型)` 資料表產生到資料庫 #### 命令 ```bash [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:status +------+------------------------------------------------+-------+ | Ran? | Migration | Batch | +------+------------------------------------------------+-------+ | Yes | 2014_10_12_000000_create_users_table | 1 | | Yes | 2014_10_12_100000_create_password_resets_table | 1 | | No | 2019_03_20_221753_create_films_table | | | No | 2019_03_20_221825_create_comments_table | | | No | 2019_03_20_221830_create_genres_table | | +------+------------------------------------------------+-------+ [alex@nvda ~/jobs/testAuth ]$ php artisan migrate Migrating: 2019_03_20_221753_create_films_table Migrated: 2019_03_20_221753_create_films_table Migrating: 2019_03_20_221825_create_comments_table Migrated: 2019_03_20_221825_create_comments_table Migrating: 2019_03_20_221830_create_genres_table Migrated: 2019_03_20_221830_create_genres_table [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:status +------+------------------------------------------------+-------+ | Ran? | Migration | Batch | +------+------------------------------------------------+-------+ | Yes | 2014_10_12_000000_create_users_table | 1 | | Yes | 2014_10_12_100000_create_password_resets_table | 1 | | Yes | 2019_03_20_221753_create_films_table | 2 | | Yes | 2019_03_20_221825_create_comments_table | 2 | | Yes | 2019_03_20_221830_create_genres_table | 2 | +------+------------------------------------------------+-------+ [alex@nvda ~/jobs/testAuth ]$ ``` 進入 mysql 用 show tables 查看 #### 執行結果 ```shell mysql> show tables; +-----------------------+ | Tables_in_d1_lta1 | +-----------------------+ | comments | | films | | genres | | migrations | | users | +-----------------------+ 5 rows in set (0.00 sec) ``` ### 生產一條龍 #### 命令 ```bash php artisan db:seed ``` 先一直按 `ENTER` 用 Seeder 程式內的預設值, 可能會順利一點, 第二次再試試調整不同的設定值, 打錯了, 可能會發生錯誤, 再去比對 Seeder 程式碼做修正. #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ php artisan db:seed 請問在資料填充前, 是否要清空所有資料表並重新建立, 原資料庫會全數刪除 ? Do you wish to refresh migration before seeding, it will clear all old data ? (yes/no) [no]: > Seeding: GenreTableSeeder 請問要生產多少種類型 (genres) ? [10]: > 工廠生產將會建立 {$count} 筆 genres (類型). Genres(類型) 生產建立完成! Seeding: UserFilmSeeder 請問要生產多少個 users (會員) ? [8]: > 請問每位 user 要生產多少支 films (影片) ? 務必要輸入 - 在兩個數字之間, 例如 3-8, 否則會發生錯誤 [0-10]: > 工廠生產將會建立 {$userCount} 個 users , 每位 user (會員) 會生產 films (影片) 的範圍為 {$filmRange}. Users(會員)及Films(影片) 生產建立完成! Seeding: CommentTableSeeder 請問每支 film (影片) 要生產多少個 comments (評論) ? 務必要輸入 - 在兩個數字之間, 例如 3-8, 否則會發生錯誤 [5-9]: > 工廠生產將會建立 {$commentRange} 不等的 comments (評論)數, 給 {$films->count()} 支 films (影片). Comments(評論) 生產建立完成! 資料庫資料填充完成. Database seeded. Database seeding completed successfully. [alex@nvda ~/jobs/testAuth ]$ [alex@nvda ~/jobs/testAuth ]$ ``` 進入 mysql 查看工廠大量生產 `films, genres, comments` 假資料的狀況 Film(影片), Genre(類型), Comment(評論) ### 查看資料表 > **注意** `MYDATABASE` 要改成自己使用的 `database 名稱` #### 命令 ```bash SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema in ('MYDATABASE') AND table_name in ('films', 'genres', 'comments') LIMIT 9; ``` #### 執行結果 ```shell mysql> SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema in ('MYDATABASE') AND table_name in ('films', 'genres', 'comments', 'users') LIMIT 9; +------------+------------+ | table_name | table_rows | +------------+------------+ | comments | 251 | | films | 36 | | genres | 10 | +------------+------------+ 3 rows in set (0.00 sec) ``` ### 用 migrate:rollback 重來一次 db:seed 正常來說, 如果不要使用 `migrate:fresh` 重設所有資料表, 它會一直累加填充 (INSERT) 資料進去資料表 現在我們練習 `migrate:rollback`, 這個命令, 會 DROP 最後一次 CREATE 的 TABLE, 就是 `films, genres, comments` 這三個資料表, 所以它不會影響到上一次或更早以前已經 CREATE 的 TABLE #### 命令 ```bash [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:rollback Rolling back: 2019_03_20_221830_create_genres_table Rolled back: 2019_03_20_221830_create_genres_table Rolling back: 2019_03_20_221825_create_comments_table Rolled back: 2019_03_20_221825_create_comments_table Rolling back: 2019_03_20_221753_create_films_table Rolled back: 2019_03_20_221753_create_films_table [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:status +------+------------------------------------------------+-------+ | Ran? | Migration | Batch | +------+------------------------------------------------+-------+ | Yes | 2014_10_12_000000_create_users_table | 1 | | Yes | 2014_10_12_100000_create_password_resets_table | 1 | | Yes | 2019_03_18_110234_create_permission_tables | 1 | | No | 2019_03_20_221753_create_films_table | | | No | 2019_03_20_221825_create_comments_table | | | No | 2019_03_20_221830_create_genres_table | | +------+------------------------------------------------+-------+ [alex@nvda ~/jobs/testAuth ]$ ``` 進入 mysql 用 show tables 查看 #### 執行結果 ```shell mysql> show tables; +-----------------------+ | Tables_in_d1_lta1 | +-----------------------+ | migrations | | users | +-----------------------+ 2 rows in set (0.00 sec) ``` 這個時候 3 個資料表都會消失, 所以我們再用 `php artisan migrate` 重建 #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ php artisan migrate Migrating: 2019_03_20_221753_create_films_table Migrated: 2019_03_20_221753_create_films_table Migrating: 2019_03_20_221825_create_comments_table Migrated: 2019_03_20_221825_create_comments_table Migrating: 2019_03_20_221830_create_genres_table Migrated: 2019_03_20_221830_create_genres_table [alex@nvda ~/jobs/testAuth ]$ php artisan migrate:status +------+------------------------------------------------+-------+ | Ran? | Migration | Batch | +------+------------------------------------------------+-------+ | Yes | 2014_10_12_000000_create_users_table | 1 | | Yes | 2014_10_12_100000_create_password_resets_table | 1 | | Yes | 2019_03_18_110234_create_permission_tables | 1 | | Yes | 2019_03_20_221753_create_films_table | 2 | | Yes | 2019_03_20_221825_create_comments_table | 2 | | Yes | 2019_03_20_221830_create_genres_table | 2 | +------+------------------------------------------------+-------+ [alex@nvda ~/jobs/testAuth ]$ ``` 此刻, 這三個資料表都是空的 GOTO `生產一條龍` 多試幾次 :-D ### 還有一件事...本地中文化 剛剛作出來的假資料, 內容都是英文, 但是, 也可以生產中文假資料, 我們只要修改 `config/app.php` 裡的 `'faker_locale'` 值為 'zh_TW' 即可, 預設為 'en_US' #### 命令 ```bash vi config/app.php ``` #### 執行結果 ```shell 'faker_locale' => 'zh_TW', // 'en_US', ``` 存檔, 再 GOTO `生產一條龍`, 查看資料庫, 嘿嘿......有中文, 有中文, 有中文, 雖然不完美 #### git ```bash git add . git commit -m '在 branch seed2 做 seeder 小實驗' git log -3 git checkout master ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ git log -3 1 commit 970bc558d0fad5afdc7465b84ce07640bf88338c (HEAD -> seeder2) 2 Author: ak4 3 Date: Thu Mar 21 20:34:04 2019 +0800 4 5 在 branch seed2 做 seeder 小實驗 6 7 commit c693f76397b85400e6effd441848a8888b5c8cc4 (master) 8 Author: ak4 9 Date: Wed Mar 20 20:04:07 2019 +0800 10 11 laravel 資料庫 Seeder 練習 12 13 database/seeds/UsersTableSeeder.php 14 15 commit 57c8cdbdf9cec7169a690ac99132564284b9e6c4 16 Author: ak4 17 Date: Wed Mar 20 12:38:39 2019 +0800 18 19 Daily Commit @190319 [alex@nvda ~/jobs/testAuth ]$ [alex@nvda ~/jobs/testAuth ]$ git checkout master Switched to branch 'master' [alex@nvda ~/jobs/testAuth ]$ git log -3 1 commit c693f76397b85400e6effd441848a8888b5c8cc4 (HEAD -> master) 2 Author: ak4 3 Date: Wed Mar 20 20:04:07 2019 +0800 4 5 laravel 資料庫 Seeder 練習 6 7 database/seeds/UsersTableSeeder.php 8 9 commit 57c8cdbdf9cec7169a690ac99132564284b9e6c4 10 Author: ak4 11 Date: Wed Mar 20 12:38:39 2019 +0800 12 13 Daily Commit @190319 14 15 commit 1a0f3510cd85f1ca491d1bdbe79712bcd40f9ea3 16 Author: ak4 17 Date: Tue Mar 19 09:04:13 2019 +0800 18 19 spatie/laravel-permission 安裝 20 21 尚未測試 [alex@nvda ~/jobs/testAuth ]$ ``` 注意最後兩個 `log commit 裡的 (...)`, 跟 `branch 的 master seeder2` 有關, 當我們執行完最後 `git checkout master`, 再回去檢查檔案內容, 這個 seeder 小實驗 (bonus) 在 database/ 目錄下產生的 9 個檔案, 都完全消失了. 甚至 `config/app.php` 裡面, 為了中文本地化而設定的`'faker_locale' => 'zh_TW'` 都變回原來的 'en_US' 哈哈, 別擔心, 神奇的傑克又回來了, 我們再下一個 `git checkout seeder2` #### git ```bash git checkout seeder2 git log -3 ``` #### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ git checkout seeder2 Switched to branch 'seeder2' [alex@nvda ~/jobs/testAuth ]$ git log -3 1 commit 970bc558d0fad5afdc7465b84ce07640bf88338c (HEAD -> seeder2) 2 Author: ak4 3 Date: Thu Mar 21 20:34:04 2019 +0800 4 5 在 branch seed2 做 seeder 小實驗 6 7 commit c693f76397b85400e6effd441848a8888b5c8cc4 (master) 8 Author: ak4 9 Date: Wed Mar 20 20:04:07 2019 +0800 10 11 laravel 資料庫 Seeder 練習 12 13 database/seeds/UsersTableSeeder.php 14 15 commit 57c8cdbdf9cec7169a690ac99132564284b9e6c4 16 Author: ak4 17 Date: Wed Mar 20 12:38:39 2019 +0800 18 19 Daily Commit @190319 [alex@nvda ~/jobs/testAuth ]$ ``` 再檢查看看那些消失在亞特蘭提斯的檔案, 是否又回到地球了, 以上的動作, 等待 git 再詳細解說, 先玩玩看 999. ## 本章總結 ### 本章使用 laravel , git 命令總結 ```bash php artisan make:seeder UsersTableSeeder # 建立 Seeder Class composer dump-autoload # 重建 autoload 自動載入程式 php artisan make:model Film -m # 產生單一 Model php artisan make:factory FilmFactory --model=Film # 產生單一 factory php artisan make:seeder GenreTableSeeder # 產生單一 seeder php artisan migrate # 生成及遷移尚未處理的資料庫 php artisan migrate:rollback # 回滾最後一次遷移的資料庫 php artisan migrate:status # 資料庫最後遷移的狀態 php artisan db:seed # 產生全部 Seeder 的 seed 資料 php artisan db:seed --class=UsersTableSeeder # 產生單一 Seeder 的 seed 資料 git branch # 查看 git 分支及現在位置 git branch -a # 查看 git 分支及現在位置 git branch seeder2 # 建立新的 git 分支, 並切換到此分支位置 git log -3 # 查看 git 現在位置的最後 3 筆 commit git checkout seeder2 # 切換到 seeder 分支 git checkout master # 切換到 master(主幹線) 分支 ```