Skip to main content

Models

Models are the heart of your application's data layer. They represent database tables and provide an expressive, object-oriented interface for interacting with your data. The Ecommerce\Core\Database\Query\Model class encapsulates table naming, attribute handling, relationships, and persistence.

Core Methods​

The following methods are available on all models extending the base Model class.

All Records​

Retrieve all records for the model.

Description:

The all() method returns a collection of all records in the model's table. It is equivalent to running a SELECT * query without constraints.

Method Signature:

public static function all(array|mixed $columns = ['*']): Collection

Parameters:

  • $columns - (Optional) Array of columns to select. Defaults to all columns.

Examples:

use Ecommerce\Models\Product;

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

foreach ($products as $product) {
echo $product->name;
}

// Get specific columns
$products = Product::all(['id', 'name', 'price']);

Find Record​

Retrieve a single model instance by its primary key.

Description:

The find() method retrieves a record by its primary key (usually id). If the record is found, it returns a hydrated model instance; otherwise, it returns null.

Method Signature:

public static function find(int $id): ?Model

Parameters:

  • $id - The primary key value to search for.

Examples:

// Find product with ID 1
$product = Product::find(1);

if ($product) {
echo $product->name;
}

Create Record​

Create and persist a new model instance.

Description:

The create() method creates a new model instance, assigns the provided attributes, and saves it to the database in a single operation. It adheres to the model's fillable or guarded property configuration for mass assignment protection.

Method Signature:

public static function create(array $attributes): Model

Parameters:

  • $attributes - Associative array of attributes to assign.

Examples:

// Create a new product
$product = Product::create([
'name' => 'New T-Shirt',
'sku' => 'TS-001',
'price' => 2999,
'stock' => 100
]);

echo $product->id; // The new ID is available immediately

Save Model​

Persist the model to the database.

Description:

The save() method inserts the model into the database if it's new, or updates the existing record if it already exists. It automatically manages created_at and updated_at timestamps if enabled.

Method Signature:

public function save(): bool

Examples:

// Create a new instance and save
$product = new Product();
$product->name = 'Yellow Scarf';
$product->price = 1500;
$product->save();

// Update an existing instance
$product = Product::find(1);
$product->price = 1200;
$product->save();

Update Model​

Update attributes and persist changes.

Description:

The update() method fills the model with the given attributes and saves it. This is a convenient shortcut for fill() followed by save().

Method Signature:

public function update(array $attributes = []): bool

Parameters:

  • $attributes - Associative array of attributes to update.

Examples:

$product = Product::find(1);

// Update specific fields
$product->update([
'price' => 1800,
'stock' => 50
]);

Delete Model​

Delete the model's record from the database.

Description:

The delete() method removes the record associated with the model instance from the database.

Method Signature:

public function delete(): bool

Examples:

$product = Product::find(1);

if ($product) {
$product->delete();
}

Destroy Records​

Delete one or more models by primary key.

Description:

The destroy() method deletes records by their primary key without retrieving the model instances first (unless model events are needed, though currently implementation fetches models first).

Method Signature:

public static function destroy(mixed $ids): int

Parameters:

  • $ids - Single ID, array of IDs, or list of IDs.

Examples:

// Delete single record
Product::destroy(1);

// Delete multiple records
Product::destroy([1, 2, 3]);

// Delete multiple records (variadic)
Product::destroy(1, 2, 3);

Fill Attributes​

Mass assign attributes to the model.

Description:

The fill() method assigns an array of attributes to the model. It filters out any attributes that are not in the fillable array or are in the guarded array, protecting against mass assignment vulnerabilities.

Method Signature:

public function fill(array $attributes): Model

Parameters:

  • $attributes - Associative array of attributes to assign.

Examples:

$product = new Product();

// Safely fill attributes
$product->fill([
'name' => 'Blue Jeans',
'price' => 4500,
'is_admin' => true, // Ignored if not fillable
]);

Load Relationships​

Eager load relationships onto an existing model instance.

Description:

The load() method eager loads relationships for a model that has already been retrieved. This helps resolve the N+1 query problem when you decide to access relationships after the initial query.

Method Signature:

public function load(mixed $relations): Model

Parameters:

  • $relations - Relation name string or array of relation names.

Examples:

$product = Product::find(1);

// Later in the code, load variants
$product->load('variants');

// Load multiple relations
$product->load(['variants', 'images']);

Fresh Instance​

Reload the model instance from the database.

Description:

The fresh() method retrieves a fresh instance of the model from the database. The existing model instance is not affected.

Method Signature:

public function fresh(array|string $with = []): ?Model

Parameters:

  • $with - (Optional) Relations to eager load on the fresh instance.

Examples:

$product = Product::find(1);

// ... some external process updates the database ...

// Get a fresh copy with updated data
$freshProduct = $product->fresh();

Refresh Instance​

Refresh the current model instance from the database.

Description:

The refresh() method re-hydrates the existing model instance with fresh data from the database. It also resets any loaded relationships.

Method Signature:

public function refresh(): Model

Examples:

$product = Product::find(1);

// ... perform operations ...

// Refresh attributes in-place
$product->refresh();

Mass Assignment​

Mass assignment allows you to send an array of data to the model creation or update methods. However, to protect your application from security vulnerabilities, you must define which attributes are assignable.

Fillable Attributes​

To whitelist attributes that can be mass assigned, use the $fillable property.

Description:

The $fillable property specifies which attributes allowed to be mass assigned.

Methods:

Get Fillable Attributes​

public function get_fillable(): array

Set Fillable Attributes​

public function fillable(array $fillable): static

Merge Fillable Attributes​

public function merge_fillable(array $fillable): static

Examples:

class Product extends Model
{
protected $fillable = ['name', 'price', 'description'];
}

// In usage
$product = new Product();
$product->fillable(['name', 'price']); // Dynamically set fillable

Guarded Attributes​

Alternatively, you can blacklist attributes using the $guarded property.

Description:

The $guarded property specifies which attributes are NOT allowed to be mass assigned. Use ['*'] to protect all attributes.

Methods:

Get Guarded Attributes​

public function get_guarded(): array

Set Guarded Attributes​

public function guard(array $guarded): static

Merge Guarded Attributes​

public function merge_guarded(array $guarded): static

Unguard Attributes​

Temporarily disable mass assignment protection.

public static function unguard(bool $state = true): void

Reguard Attributes​

Re-enable mass assignment protection.

public static function reguard(): void

Examples:

class User extends Model
{
protected $guarded = ['is_admin'];
}

// Temporarily unguard
Model::unguard();
User::create(['name' => 'Admin', 'is_admin' => true]);
Model::reguard();

Mutators & Casting​

Mutators and casting allow you to transform attribute values when you retrieve or set them on model instances.

Accessors & Mutators​

And accessor transforms an attribute value when it is accessed. A mutator transforms an attribute value when it is set.

Naming Convention:

  • Accessor: get_{Attribute}_attribute
  • Mutator: set_{Attribute}_attribute

Examples:

class User extends Model
{
// Accessor: Get name in uppercase
public function get_name_attribute($value)
{
return strtoupper($value);
}

// Mutator: Hash password before saving
public function set_password_attribute($value)
{
$this->attributes['password'] = password_hash($value, PASSWORD_BCRYPT);
}
}

Attribute Casting​

Attribute casting provides a convenient way to convert attributes to common data types.

Supported Cast Types:

  • int
  • integer
  • real
  • float
  • double
  • decimal:digits
  • string
  • bool
  • boolean
  • object
  • array
  • json
  • date
  • datetime
  • timestamp

Description:

The $casts property maps attribute names to the desired cast type.

Methods:

Get Casts​

public function get_casts(): array

Merge Casts​

public function merge_casts(array $casts): static

Examples:

class Product extends Model
{
protected $casts = [
'is_active' => 'boolean',
'options' => 'array',
'price' => 'decimal:2',
'published_at' => 'datetime'
];
}

$product = Product::find(1);
var_dump($product->is_active); // bool(true)
var_dump($product->options); // array(...)

Scopes​

Scopes allow you to define common sets of constraints that you may easily re-use throughout your application.

Named Scopes​

Description:

Named scopes are defined by adding a scope_ prefix to a method name. These methods should return the query builder instance.

Methods:

Check Named Scope​

public function has_named_scope(string $scope): bool

Examples:

class Product extends Model
{
// Define scope 'active'
public function scope_active($query)
{
return $query->where('is_active', true);
}

// Define scope 'price_greater_than'
public function scope_price_greater_than($query, $price)
{
return $query->where('price', '>', $price);
}
}

// Usage
$activeProducts = Product::query()->active()->get();

$expensiveProducts = Product::query()->price_greater_than(100)->get();