Unit 6 - Notes

INT221 1 min read

Unit 6: Getting started with databases

1. Model Creation

In the Model-View-Controller (MVC) architecture, the Model is responsible for managing data, logic, and rules of the application. In Laravel, models interact with the database using Eloquent ORM. Each database table has a corresponding "Model" that is used to interact with that table.

1.1 Creating a Model

Models are typically stored in the app/Models directory. The easiest way to create a model instance is via the Artisan command line interface (CLI).

Command:

BASH
php artisan make:model Product

Command with Migration:
To generate a migration file simultaneously (recommended practice):

BASH
php artisan make:model Product -m

1.2 Model Conventions

Laravel follows the "Convention over Configuration" philosophy:

  • Class Name: Singular, CamelCase (e.g., Product).
  • Table Name: Plural, Snake_case (e.g., products).
  • Primary Key: Assumes a column named id.
  • Timestamps: Assumes created_at and updated_at columns exist.

1.3 Customizing the Model

If the legacy database does not follow these conventions, they can be overridden in the model class.

PHP
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    // Override table name
    protected $table = 'my_products';

    // Override primary key
    protected $primaryKey = 'product_id';

    // Disable timestamps
    public $timestamps = false;

    // Mass Assignment Protection (Allowable columns)
    protected $fillable = ['name', 'price', 'description'];
}


2. Migrations

Migrations are like version control for your database, allowing your team to define and share the application's database schema definition.

2.1 Creating Migrations

When running make:model -m, the migration is created in database/migrations. You can also create one manually:

BASH
php artisan make:migration create_products_table

2.2 Migration Structure

A migration file contains two main methods:

  1. up(): Used to add new tables, columns, or indexes to the database.
  2. down(): Used to reverse the operations performed by the up method.

Example Migration:

PHP
public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->id(); // Auto-incrementing unsigned big int
        $table->string('name');
        $table->text('description')->nullable();
        $table->decimal('price', 8, 2);
        $table->boolean('is_active')->default(true);
        $table->timestamps(); // created_at and updated_at
    });
}

public function down()
{
    Schema::dropIfExists('products');
}

2.3 Running Migrations

  • Run pending migrations: php artisan migrate
  • Rollback the last batch: php artisan migrate:rollback
  • Rollback all and re-run: php artisan migrate:fresh

3. CRUD Using Query Builder

Laravel's Database Query Builder provides a convenient, fluent interface to creating and running database queries. It can be used to perform most database operations and works on all supported database systems. It uses the DB facade.

3.1 Create (Insert)

PHP
use Illuminate\Support\Facades\DB;

DB::table('products')->insert([
    'name' => 'Laptop',
    'price' => 999.99,
    'created_at' => now()
]);

3.2 Read (Select)

  • Get all rows:
    PHP
        $products = DB::table('products')->get();
        
  • Get specific row:
    PHP
        $product = DB::table('products')->where('name', 'Laptop')->first();
        
  • Pluck specific column:
    PHP
        $titles = DB::table('products')->pluck('name');
        

3.3 Update

PHP
DB::table('products')
    ->where('id', 1)
    ->update(['price' => 899.99]);

3.4 Delete

PHP
DB::table('products')->where('id', 1)->delete();

// Delete all records (Truncate)
DB::table('products')->truncate();


4. Seeding

Seeding allows you to populate your database with test data or initial system data (like default admin users or categories).

4.1 Creating a Seeder

BASH
php artisan make:seeder ProductSeeder

4.2 Writing Seeder Logic

Inside the run method of the generated seeder class:

PHP
// database/seeders/ProductSeeder.php
public function run()
{
    // Using Query Builder
    DB::table('products')->insert([
        'name' => 'Sample Product',
        'price' => 10.00,
    ]);

    // OR Using Factories (Recommended for large data)
    \App\Models\Product::factory()->count(50)->create();
}

4.3 Running Seeders

  1. Run specific seeder: php artisan db:seed --class=ProductSeeder
  2. Run all seeders (registered in DatabaseSeeder): php artisan db:seed
  3. Migrate and Seed: php artisan migrate:fresh --seed

5. CRUD Using Eloquent ORM

Eloquent is an Object-Relational Mapper (ORM) that makes interacting with the database enjoyable by representing database tables as classes.

5.1 Create

To create a new record, instantiate the model, set attributes, and save.

Method 1: Instance

PHP
$product = new Product;
$product->name = 'Smartphone';
$product->price = 699.00;
$product->save();

Method 2: Mass Assignment (create method)
Note: Requires $fillable property to be set in the Model.

PHP
$product = Product::create([
    'name' => 'Smartphone',
    'price' => 699.00
]);

5.2 Read

PHP
// Get all records
$products = Product::all();

// Find by Primary Key
$product = Product::find(1);

// Find or throw 404 error (useful for APIs)
$product = Product::findOrFail(1);

// Complex queries
$activeProducts = Product::where('is_active', 1)
                ->orderBy('price', 'desc')
                ->take(10)
                ->get();

5.3 Update

Retrieve the record first, modify properties, then save.

PHP
$product = Product::find(1);
$product->price = 599.00;
$product->save();

// Mass Update
Product::where('is_active', 1)->update(['is_active' => 0]);

5.4 Delete

PHP
// Method 1: Retrieve and delete
$product = Product::find(1);
$product->delete();

// Method 2: Destroy by ID
Product::destroy(1);
Product::destroy([1, 2, 3]); // Destroy multiple


6. Using MongoDB with Laravel

Laravel supports SQL databases (MySQL, PostgreSQL) out of the box. To use MongoDB (a NoSQL database), an external package is required. The most common is the official mongodb/laravel-mongodb driver (formerly Jenssegers).

6.1 Installation and Configuration

  1. Install via Composer:
    BASH
        composer require mongodb/laravel-mongodb
        
  2. Configure config/database.php:
    Add a new connection under connections:
    PHP
        'mongodb' => [
            'driver'   => 'mongodb',
            'host'     => env('DB_HOST', '127.0.0.1'),
            'port'     => env('DB_PORT', 27017),
            'database' => env('DB_DATABASE', 'homestead'),
            'username' => env('DB_USERNAME', 'homestead'),
            'password' => env('DB_PASSWORD', 'secret'),
        ],
        
  3. Update .env: Change DB_CONNECTION=mongodb.

6.2 Eloquent with MongoDB

Since MongoDB is schemaless, Models must extend the MongoDB Eloquent class, not the standard Laravel class.

PHP
namespace App\Models;

use MongoDB\Laravel\Eloquent\Model; // Import specific MongoDB Model

class Product extends Model
{
    protected $connection = 'mongodb';
    protected $collection = 'products'; // MongoDB uses collections, not tables
}

6.3 Key Differences

  • Primary Keys: MongoDB uses _id (ObjectId) instead of auto-incrementing integers.
  • Schema: Migrations are not strictly required to create tables, as MongoDB creates collections on the fly. However, migrations can still be used for creating indexes.
  • Embedded Documents: MongoDB allows nested arrays which Eloquent handles natively.
    PHP
        $product = Product::create([
            'name' => 'Gadget',
            'details' => ['color' => 'red', 'weight' => '200g'] // Stored as JSON object
        ]);
        

7. Implementing REST APIs

Laravel is widely used for building RESTful APIs. These APIs return JSON responses instead of HTML views.

7.1 API Routes

API routes are defined in routes/api.php.

  • Routes here automatically have the /api prefix.
  • They use the api middleware group (stateless, no sessions).

PHP
use App\Http\Controllers\ProductController;

Route::get('/products', [ProductController::class, 'index']);
Route::post('/products', [ProductController::class, 'store']);
Route::get('/products/{id}', [ProductController::class, 'show']);
Route::put('/products/{id}', [ProductController::class, 'update']);
Route::delete('/products/{id}', [ProductController::class, 'destroy']);

// Or use the resource shortcut
Route::apiResource('products', ProductController::class);

7.2 Controller Structure

Create a controller: php artisan make:controller ProductController --api.

Returning JSON:
Laravel automatically converts Arrays and Collections to JSON when returned from a controller.

PHP
public function index()
{
    return Product::all(); // Returns JSON array of objects
}

public function store(Request $request)
{
    $validated = $request->validate([
        'name' => 'required|string',
        'price' => 'required|numeric'
    ]);

    $product = Product::create($validated);

    // Return data with 201 Created status code
    return response()->json($product, 201);
}

7.3 API Resources

To transform the data before sending it (e.g., hiding database columns or renaming keys), use API Resources.

Create Resource:

BASH
php artisan make:resource ProductResource

Define Transformation:

PHP
// app/Http/Resources/ProductResource.php
public function toArray($request)
{
    return [
        'id' => $this->id,
        'product_name' => $this->name, // Renaming key
        'cost' => $this->price . ' USD', // Formatting
        // Hiding created_at/updated_at
    ];
}

Usage in Controller:

PHP
public function show($id)
{
    $product = Product::findOrFail($id);
    return new ProductResource($product);
}