Eloquent Models
Introduction
Eloquent models encapsulate your database tables into clean, object-oriented PHP classes. Each model contains attributes that map to the underlying table columns, along with helper methods to handle validation, casting, serialization, and scopes.
Model Definition & Attributes
Here is an example of an Eloquent model definition demonstrating common configuration properties:
<?php
declare(strict_types=1);
namespace App\Models;
use Lacelium\Core\Model;
class Product extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'products';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'sku',
'name',
'price',
'metadata',
'is_published',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'price' => 'float',
'metadata' => 'array',
'is_published' => 'boolean',
'published_at' => 'datetime',
];
}
Mass Assignment
Mass assignment is the process of setting multiple model attributes simultaneously using an array. To prevent vulnerabilities where users unintentionally overwrite sensitive columns (like is_admin), you must define either $fillable or $guarded.
// Allowed attributes for mass assignment:
protected $fillable = ['name', 'email', 'bio'];
// Or block specific attributes and allow all others:
protected $guarded = ['id', 'is_admin'];
Once defined, you can safely use create or fill:
$product = Product::create($request->all());
Attribute Casting
Attribute casting provides functionality similar to accessors and mutators without requiring you to define separate methods on your model. Supported cast types include integer, float, string, boolean, array, json, and datetime.
// The 'metadata' column is stored as JSON in the database,
// but automatically converted to a PHP array when accessed:
$product = Product::find(1);
$options = $product->metadata['options'];
// And automatically re-serialized to JSON when saved:
$product->metadata = ['color' => 'blue', 'size' => 'large'];
$product->save();
Local Query Scopes
Local scopes allow you to define common sets of query constraints that you may easily re-use throughout your application. To define a scope, prefix an Eloquent model method with scope:
public function scopePublished($query)
{
return $query->where('is_published', true);
}
public function scopePopular($query, int $minOrders = 100)
{
return $query->where('orders_count', '>=', $minOrders);
}
Utilizing a Local Scope
Once the scope has been defined, you may call the scope methods when querying the model. You do not need to include the scope prefix when chaining methods:
use App\Models\Product;
$products = Product::published()->popular(50)->get();
Next Steps
- Connect related models in Eloquent Relationships.
- Avoid N+1 queries using Eager Loading.
- Explore the visual schema explorer in ArgusKit Studio.