Model (ORM)
Model là lớp đại diện cho một bảng trong database, cho phép tương tác với dữ liệu theo hướng đối tượng.
Định nghĩa Model
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
class User extends Model
{
// Tên bảng (mặc định là snake_case của tên class + 's')
protected string $table = 'users';
// Primary key (mặc định là 'id')
protected ?string $primaryKey = 'id';
// Có dùng auto-increment không
protected bool $incrementing = true;
// Có dùng timestamps không (created_at, updated_at)
public bool $timestamps = true;
// Connection database (null = default)
protected ?string $connection = null;
}
Truy vấn cơ bản
use App\Models\User;
// Lấy tất cả
$users = User::get();
// Lấy theo ID
$user = User::find(1);
// Lấy hoặc throw exception
$user = User::findOrFail(1);
// Lấy record đầu tiên
$user = User::where('status', 'active')->first();
// Đếm
$count = User::where('role', 'admin')->count();
Tạo mới
// Tạo và lưu
$user = User::create([
'name' => 'John',
'email' => 'john@example.com',
]);
// firstOrCreate - tìm hoặc tạo mới
$user = User::firstOrCreate(
['email' => 'john@example.com'], // điều kiện tìm
['name' => 'John'] // dữ liệu tạo mới
);
// firstOrNew - tìm hoặc tạo instance (chưa save)
$user = User::firstOrNew(
['email' => 'john@example.com'],
['name' => 'John']
);
// updateOrCreate - cập nhật hoặc tạo mới
$user = User::updateOrCreate(
['email' => 'john@example.com'],
['name' => 'John Doe', 'role' => 'admin']
);
Cập nhật
// Cập nhật instance
$user = User::find(1);
$user->name = 'Jane';
$user->save();
// Update trực tiếp
User::where('id', 1)->update(['name' => 'Jane']);
// Cập nhật nhiều records
User::where('status', 'pending')
->update(['status' => 'active']);
Xóa
// Xóa instance
$user = User::find(1);
$user->delete();
// Xóa trực tiếp
User::where('id', 1)->delete();
// Xóa nhiều records
User::where('status', 'inactive')->delete();
Soft Deletes
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
use Vietiso\Core\Database\Model\Traits\SoftDeletes;
class User extends Model
{
use SoftDeletes;
}
// Xóa mềm (set deleted_at)
$user->delete();
// Kiểm tra đã xóa mềm
if ($user->trashed()) {
// ...
}
// Bao gồm cả records đã xóa mềm
$users = User::withTrashed()->get();
// Chỉ lấy records đã xóa mềm
$users = User::onlyTrashed()->get();
// Khôi phục record đã xóa mềm
$user->restore();
// Xóa vĩnh viễn
$user->forceDelete();
Accessors & Mutators
Sử dụng attributes để định nghĩa accessors và mutators:
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
use Vietiso\Core\Database\Attributes\Accessor;
use Vietiso\Core\Database\Attributes\Mutator;
class User extends Model
{
// Accessor - chuyển đổi khi lấy dữ liệu
#[Accessor('name')]
public function getNameAttribute(string $value): string
{
return ucfirst($value);
}
// Mutator - chuyển đổi khi gán dữ liệu
#[Mutator('password')]
public function setPasswordAttribute(string $value): string
{
return password_hash($value, PASSWORD_DEFAULT);
}
// Accessor cho computed attribute
#[Accessor('full_name')]
public function getFullNameAttribute(): string
{
return "{$this->first_name} {$this->last_name}";
}
}
$user = User::find(1);
echo $user->full_name; // John Doe
Attribute Casting
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
class User extends Model
{
protected array $casts = [
'is_active' => 'boolean',
'settings' => 'array',
'birthday' => 'date',
'created_at' => 'datetime',
'price' => 'float',
'count' => 'integer',
];
}
Custom Casts
<?php
namespace App\Casts;
use Vietiso\Core\Database\Model\Casts\CastsAttributes;
class JsonCast implements CastsAttributes
{
public function get($model, string $key, $value, array $attributes): array
{
return json_decode($value, true) ?? [];
}
public function set($model, string $key, $value, array $attributes): string
{
return json_encode($value);
}
}
protected array $casts = [
'metadata' => JsonCast::class,
];
Relationships
One to One
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
use Vietiso\Core\Database\Attributes\HasOne;
use Vietiso\Core\Database\Attributes\BelongsTo;
class User extends Model
{
#[HasOne(Profile::class, 'user_id')]
public function profile() {}
}
class Profile extends Model
{
#[BelongsTo(User::class, 'user_id')]
public function user() {}
}
One to Many
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
use Vietiso\Core\Database\Attributes\HasMany;
use Vietiso\Core\Database\Attributes\BelongsTo;
class User extends Model
{
#[HasMany(Post::class, 'user_id')]
public function posts() {}
}
class Post extends Model
{
#[BelongsTo(User::class, 'user_id')]
public function user() {}
}
Sử dụng Relationships
// Eager loading
$users = User::with('posts')->get();
// Nested eager loading
$users = User::with('posts.comments')->get();
// Lazy loading
$user = User::find(1);
$posts = $user->posts;
// Query relationship
$user = User::find(1);
$publishedPosts = $user->posts()->where('status', 'published')->get();
Global Scopes
<?php
namespace App\Models\Scopes;
use Vietiso\Core\Database\Model\Scopes\Scope;
use Vietiso\Core\Database\Model\Builder;
use Vietiso\Core\Database\Model\Model;
class ActiveScope implements Scope
{
public function apply(Builder $builder, Model $model): void
{
$builder->where('is_active', true);
}
}
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
use Vietiso\Core\Database\Attributes\GlobalScope;
use App\Models\Scopes\ActiveScope;
#[GlobalScope(ActiveScope::class)]
class User extends Model
{
}
// Query tự động thêm WHERE is_active = true
$users = User::get();
// Bỏ global scope
$users = User::withoutGlobalScope(ActiveScope::class)->get();
// Bỏ nhiều global scopes
$users = User::withoutGlobalScopes([
ActiveScope::class,
AnotherScope::class,
])->get();
Local Scopes
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
use Vietiso\Core\Database\Attributes\Scope;
use Vietiso\Core\Database\Model\Builder;
class User extends Model
{
#[Scope]
public function scopeActive(Builder $query): Builder
{
return $query->where('is_active', true);
}
#[Scope]
public function scopeRole(Builder $query, string $role): Builder
{
return $query->where('role', $role);
}
}
// Sử dụng scopes
$users = User::active()->get();
$admins = User::active()->role('admin')->get();
Model Events
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
use Vietiso\Core\Database\Attributes\Event;
class User extends Model
{
#[Event('creating')]
public static function onCreating(User $user): void
{
$user->uuid = generate_uuid();
}
#[Event('created')]
public static function onCreated(User $user): void
{
// Gửi email chào mừng
}
#[Event('updating')]
public static function onUpdating(User $user): void
{
// Trước khi update
}
#[Event('updated')]
public static function onUpdated(User $user): void
{
// Sau khi update
}
#[Event('deleting')]
public static function onDeleting(User $user): void
{
// Trước khi delete
}
#[Event('deleted')]
public static function onDeleted(User $user): void
{
// Sau khi delete
}
}
Hidden & Visible Attributes
<?php
namespace App\Models;
use Vietiso\Core\Database\Model\Model;
class User extends Model
{
// Ẩn khi serialize (toArray, toJson)
protected array $hidden = ['password', 'remember_token'];
// Hoặc chỉ hiện các fields này
protected array $visible = ['id', 'name', 'email'];
}
Serialization
$user = User::find(1);
// Chuyển thành array
$array = $user->toArray();
// Chuyển thành JSON
$json = $user->toJson();
// Tự động serialize khi return trong controller
return $user; // Trả về JSON