Chuyển đến nội dung chính

第 5 課:遷移、播種與查詢產生器

資料庫遷移、模式建構器。工廠(樣品工廠)、播種者。查詢產生器、原始查詢、分頁。資料庫事務、資料庫測試。

💻 程式設計 — 第 5 課 第 5 課:遷移、播種與查詢產生器

Laravel:從基礎到高級

第 2 部分:資料庫和驗證

亞洲開發網

1. 遷移

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

return new class extends Migration {
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('slug')->unique();
            $table->text('description')->nullable();
            $table->decimal('price', 10, 2);
            $table->integer('stock')->default(0);
            $table->foreignId('category_id')->constrained()->cascadeOnDelete();
            $table->boolean('is_active')->default(true);
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->softDeletes();

            $table->index(['category_id', 'is_active']);
            $table->fullText('name');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};
php artisan make:migration add_discount_to_products --table=products
php artisan migrate
php artisan migrate:rollback --step=1
php artisan migrate:fresh --seed  # Drop all & re-run

2. 模型工廠

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class ProductFactory extends Factory
{
    public function definition(): array
    {
        return [
            'name' => fake()->sentence(3),
            'slug' => fake()->unique()->slug(),
            'description' => fake()->paragraphs(2, true),
            'price' => fake()->randomFloat(2, 10, 1000),
            'stock' => fake()->numberBetween(0, 100),
            'category_id' => Category::factory(),
            'is_active' => true,
        ];
    }

    public function inactive(): static
    {
        return $this->state(fn () => ['is_active' => false]);
    }
}

// Sử dụng
Product::factory()->count(50)->create();
Product::factory()->inactive()->create();

3. 播種機

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        $this->call([CategorySeeder::class]);
        Product::factory()->count(100)->create();
        User::factory()->count(10)->create();
    }
}

4. 查詢產生器

use Illuminate\Support\Facades\DB;

$results = DB::table('products')
    ->join('categories', 'products.category_id', '=', 'categories.id')
    ->select('products.*', 'categories.name as category_name')
    ->where('products.is_active', true)
    ->whereBetween('price', [100, 500])
    ->orderByDesc('created_at')
    ->paginate(20);

// Transactions
DB::transaction(function () {
    $order = Order::create([...]);
    foreach ($items as $item) {
        $order->items()->create($item);
        Product::where('id', $item['product_id'])->decrement('stock', $item['quantity']);
    }
});

下一篇: 驗證和表格請求。