# 前言
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法
; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。
# Writing Seeders
以下 Laravel command 的意思是?
- Example:
php artisan make:seeder UserSeeder
- Answer:
建立一個 seed class
以下 Laravel example code 的意思是?
- Example:
<?php
class DatabaseSeeder extends Seeder
{
public function run()
{
DB::table('users')->insert([
'name' => Str::random(10),
'email' => Str::random(10).'@gmail.com',
'password' => Hash::make('password'),
]);
}
} - Answer:
<?php
class DatabaseSeeder extends Seeder
{
public function run()
{
DB::table('users')->insert([
// 隨機產生 10 碼
'name' => Str::random(10),
// 同上
'email' => Str::random(10).'@gmail.com',
// 將 string 'password' hash 存到資料庫
'password' => Hash::make('password'),
]);
}
}
# Using Model Factories
以下 Laravel example code 的意思是?
- Example:
php artisan make:factory PostFactory --model=Post
- Answer:
建立一個 PostFactory, 該 factory 會產生 Post model
以下 Laravel example code 的意思是?
- Example:
<?php
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
} - Answer:
<?php
class UserFactory extends Factory
{
// 該 factory 對應的 model
protected $model = User::class;
// 定義 model 預設的狀態
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
}
以下 Laravel 中, 位於 Factory 中的 example code 的意思是?
- Example:
<?php
public function suspended()
{
return $this->state(function (array $attributes) {
return [
'account_status' => 'suspended',
];
});
} - Answer:
自定義一個 factory method
以下 Laravel 中, 位於 Factory 中的 example code 的意思是?
- Example:
<?php
class UserFactory extends Factory
{
protected $model = User::class;
public function configure()
{
return $this->afterMaking(function (User $user) {
//
})->afterCreating(function (User $user) {
//
});
}
// ...
} - Answer:
<?php
class UserFactory extends Factory
{
指定要建立的 model
protected $model = User::class;
public function configure()
{
// make model 後要做的事
return $this->afterMaking(function (User $user) {
//
// create model 後要做的事
})->afterCreating(function (User $user) {
//
});
}
// ...
}
以下 Laravel 中, 位於 model 內的 example code 的意思是?
- Example:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use HasFactory;
} - Answer:
當特定 model 的 Factory 被定義後, 可在 model 中 use HasFactory trait, 這樣就可以在任何地方使用 static factory method
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
use App\Models\User;
public function testDatabase()
{
$user = User::factory()->make();
// Use model in tests...
} - Answer:
使用 factory 來 make 一個 User model, make 表示已建立但尚未儲存到資料庫
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$users = User::factory()->count(3)->make(); - Answer:
使用 user factory make 3 個 User model, make 表示已建立 model 但尚未儲存到資料庫
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
protected static function newFactory()
{
return \Database\Factories\Administration\FlightFactory::new();
} - Answer:
HasFactory trait 中的 factor method 有其規定的 convention, 像是 modelNameFactory, 如 PostFactory, 當使用 Post::factory() 時 Laravel 會自動尋找 Factory namespace 下面的 PostFactory
上面的 example code 是當 Factory 不符合這個 convention 時, 可以特別指定
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$users = User::factory()->count(5)->suspended()->make(); - Answer:
suspended() 為自定義的 state method, 也可被使用
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()->make([
'name' => 'Abigail Otwell',
]); - Answer:
一般來說, factory 會 return 在 factory 中定義好的 attributes, 但若臨時要特別指定 attributes, 可用以上的 example code
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()->state([
'name' => 'Abigail Otwell',
])->make(); - Answer:
一般來說, factory 會 return 在 factory 中定義好的 attributes, 但若臨時要特別指定 attributes, 可用以上的 example code
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
use App\Models\User;
public function testDatabase()
{
$user = User::factory()->create();
$users = User::factory()->count(3)->create();
} - Answer:
<?php
use App\Models\User;
public function testDatabase()
{
// 建立一筆 user model record 並 save
$user = User::factory()->create();
// 建立三筆 user model record 並 save
$users = User::factory()->count(3)->create();
}
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()->create([
'name' => 'Abigail',
]); - Answer:
一般來說, factory 會 return 在 factory 中定義好的 attributes, 但若臨時要特別指定 attributes, 可用以上的 example code
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$users = User::factory()
->count(10)
->state(new Sequence(
['admin' => 'Y'],
['admin' => 'N'],
))
->create(); - Answer:
Sequence method 可以讓建立出來的 model 輪流使用帶入的參數, 所以這十筆 model 的資料就會是 y, n, y, n, …
以下的 Laravel Testing example code 的意思是?
- Example:
<?php
$users = User::factory()
->count(10)
->state(new Sequence(
fn () => ['role' => UserRoles::all()->random()],
))
->create(); - Answer:
當使用 Sequence() 時, 也可帶入 closure, 在建立每一個 model 時 closure 都會被 invoked
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
public function definition()
{
return [
'user_id' => User::factory(),
'user_type' => function (array $attributes) {
return User::find($attributes['user_id'])->type;
},
'title' => $this->faker->title,
'content' => $this->faker->paragraph,
];
} - Answer:
<?php
public function definition()
{
return [
// 建立 post 時, 同時建立一個 user
'user_id' => User::factory(),
// attributes 裡頭會有上一行建立的 user_id, 利用此 user_id 取得 User model 及
// 其 type
'user_type' => function (array $attributes) {
return User::find($attributes['user_id'])->type;
},
'title' => $this->faker->title,
'content' => $this->faker->paragraph,
];
}
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()
->has(Post::factory()->count(3))
->create(); - Answer:
<?php
$user = User::factory()
// 在建立該 user model 的同時, 建立三個 Post model
// 須事先 define User hasMany Post 的 relation
->has(Post::factory()->count(3))
->create();
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()
->has(Post::factory()->count(3), 'posts')
->create(); - Answer:
<?php
$user = User::factory()
// create User 的同時也 create 三筆 Post, 須事先定義
// User hasMany Post relation
// 帶入 'posts' 為特別指定, 若無指定 Laravel 會使用自己的 convention 尋找
->has(Post::factory()->count(3), 'posts')
->create();
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()
->has(
Post::factory()
->count(3)
->state(function (array $attributes, User $user) {
return ['user_type' => $user->type];
})
)
->create(); - Answer:
<?php
$user = User::factory()
->has(
Post::factory()
->count(3)
// 使用 state method 在 Post model 中定義額外與 User model 相關的資訊
->state(function (array $attributes, User $user) {
return ['user_type' => $user->type];
})
)
->create();
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()
->hasPosts(3)
->create(); - Answer:
使用 factory’s magic relationship methods, 在 create User model 的同時, 並 create 三個 Post relationship model
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()
->hasPosts(3, [
'published' => false,
])
->create(); - Answer:
使用 factory’s magic relationship methods, 在 create User model 的同時, 並 create 三個 Post relationship model, 並且額外帶入 attributes 覆蓋原本的
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$user = User::factory()
->hasPosts(3, function (array $attributes, User $user) {
return ['user_type' => $user->type];
})
->create(); - Answer:
使用 factory’s magic relationship methods, 在 create User model 的同時, 並 create 三個 Post relationship model, 因為會用到 User model 的內容來更新 Post model, 因此使用了 state method
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$posts = Post::factory()
->count(3)
->for(User::factory()->state([
'name' => 'Jessica Archer',
]))
->create(); - Answer:
在 create 3 個 Post model 的同時, create 一個 belongsTo relation 的 User model, 並自定義 name column
需事先在 Post model 定義與 User model 的 belongsTo relationship
以下的 Laravel Testing example code 的意思是?
- Example:
<?php
$user = User::factory()->create();
$posts = Post::factory()
->count(3)
->for($user)
->create(); - Answer:
在使用 Factory 建立 belongsTo relationship 時, 如果已有現成的 model, 可直接 pass 該 model as a parent
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$posts = Post::factory()
->count(3)
->forUser([
'name' => 'Jessica Archer',
])
->create(); - Answer:
使用 Factory magic relationship method, create 3 個 Post model 並指定其 belongsTo User model, 並指定該 User model 的 name 為 Jessica Archer
以下的 Laravel Testing example code 的意思是?
- Example:
<?php
$user = User::factory()
->has(Role::factory()->count(3))
->create(); - Answer:
也可使用 has() 來指定 relationship, 前提是要先在 model 定義好 relation
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$users = User::factory()
->hasAttached(
Role::factory()->count(3),
['active' => true]
)
->create(); - Answer:
使用 hasAttached method 來定義 pivot table 的 attribute
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$users = User::factory()
->hasAttached(
Role::factory()
->count(3)
->state(function (array $attributes, User $user) {
return ['name' => $user->name.' Role'];
}),
['active' => true]
)
->create(); - Answer:
<?php
$users = User::factory()
// 使用 hasAttached method 來定義 pivot table 的 attribute
->hasAttached(
// 這邊具體行為, create 3 個 Role model, 並定義 name column 的 value
// 為 $user->name.' Role', 會用到 User model, 所以使用 state method
Role::factory()
->count(3)
->state(function (array $attributes, User $user) {
return ['name' => $user->name.' Role'];
}),
// 這一行定義 pivot model 的 active column 的 value 為 true
['active' => true]
)
->create();
以下的 Laravel Testing example code 的意思是?
- Example:
<?php
$roles = Role::factory()->count(3)->create();
$user = User::factory()
->count(3)
->hasAttached($roles, ['active' => true])
->create(); - Answer:
使用 hasAttached() 時, 也可直接帶入已經建立好的 models, 並定義 pivot table 上的值
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$users = User::factory()
->hasRoles(1, [
'name' => 'Editor'
])
->create(); - Answer:
create User model 並且同步 create 1 個 Role model, User 與 Role model relationship 可以是 hasMany 或 manyToMany 或 morphMany, 並 overwrite name column 的 value 為 Editor
Relationship 須事先定義
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
$comments = Comment::factory()->count(3)->for(
Post::factory(), 'commentable'
)->create(); - Answer:
使用 factory create 3 個 comment model, 並且 create 1 個 Post model, 彼此的 relationship 為 Comments morphTo Post
以下的 Laravel Testing example code 的意思是?
- Example:
<?php
use App\Models\User;
public function definition()
{
return [
'user_id' => User::factory(),
'title' => $this->faker->title,
'content' => $this->faker->paragraph,
];
} - Answer:
在 Factory 內可直接定義 relationships
以下的 Laravel Testing example code 的意思是?
- Example:
<?php
public function definition()
{
return [
'user_id' => User::factory(),
'user_type' => function (array $attributes) {
return User::find($attributes['user_id'])->type;
},
'title' => $this->faker->title,
'content' => $this->faker->paragraph,
];
} - Answer:
如果某個 attribute 的值取決於 relation model 的某個欄位, 可使用 closure, 並從 $attributes 取得當前已建立的 attributes 來進一步取得資訊
以下 Laravel 中, create hasMany 跟 morphMany 的 method 一樣嗎?
一樣
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
public function run()
{
User::factory()
->times(50)
->hasPosts(1)
->create();
} - Answer:
利用 User factory create 50 個 User model, 並且每個 User model 各 create 一個 hasMany relationship Post model
# Calling Additional Seeders
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
public function run()
{
$this->call([
UserSeeder::class,
PostSeeder::class,
CommentSeeder::class,
]);
} - Answer:
在 database seeder 中, 定義要執行的 seeder, 當我下php artisan db:seed
之後將會執行以上定義的 seeder
# Running Seeders
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
php artisan db:seed
php artisan db:seed --class=UserSeeder - Answer:
<?php
// 執行 database seeder, 會執行所有定義在 database seeder 中的動作
php artisan db:seed
// 只執行
php artisan db:seed --class=UserSeeder
以下 Laravel 中, 以下的 example code 意思是?
- Example:
<?php
php artisan migrate:fresh --seed - Answer:
migration drop 所有的 table 在執行 up 的同時, 執行 database seeder
# Forcing Seeders To Run In Production
以下 Laravel 中, 以下的 example code 意思是?
- Example:
php artisan db:seed --force
- Answer:
在 production 中, Laravel 的保護機制, 當執行php artisan db:seed
時會跳出詢問再確認的視窗, 若使用 flag--force
可略過此保護機制
留言