Laravel Eloquent ORM 指南

Eloquent ORM 模式:模型定义、关系、查询作用域、访问器/修改器和预加载。

1. 模型定义

class Article extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = ['title', 'slug', 'content', 'status', 'author_id'];
    protected $hidden = ['deleted_at'];
    protected $casts = [
        'published_at' => 'datetime',
        'metadata'     => 'array',
        'is_featured'  => 'boolean',
    ];
}

2. 关系

class Article extends Model
{
    public function author()
    {
        return $this->belongsTo(User::class, 'author_id');
    }

    public function comments()
    {
        return $this->hasMany(Comment::class)->latest();
    }

    public function tags()
    {
        return $this->belongsToMany(Tag::class, 'article_tags')
                    ->withTimestamps()
                    ->withPivot('order');
    }
}

3. 作用域

class Article extends Model
{
    public function scopePublished($query)
    {
        return $query->where('status', 'published');
    }

    public function scopeByAuthor($query, $authorId)
    {
        return $query->where('author_id', $authorId);
    }
}

$articles = Article::published()->byAuthor(1)->latest()->paginate(15);

4. 预加载

$articles = Article::with(['author', 'tags', 'comments.user'])->published()->get();

// 带约束的预加载
$articles = Article::with([
    'comments' => fn($q) => $q->where('approved', true)->latest()->take(5),
])->get();

// withCount
$articles = Article::withCount(['comments', 'likes'])->get();
// 访问: $article->comments_count

// 防止 N+1(全局)
Model::preventLazyLoading(! app()->isProduction());