You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在Laravel的Customer Model中重写get()方法实现权限化查询?

Is overriding the get() method in Laravel's Customer Model feasible?

First off, let's cut to the chase: your code will technically run in some narrow scenarios, but it's not a recommended approach—it goes against Laravel's core design principles and creates avoidable maintenance headaches. Let's break this down.

Why your current implementation has red flags

  • You're overriding the wrong method: Laravel's Model class doesn’t have a static get() method. When you call Customer::get(), the request gets forwarded to the Eloquent Builder via magic methods. Your overridden instance method get(array $options = []) won’t even trigger for the most common use case (fetching collections via static calls)—it only runs if you call it on an existing model instance, which is rarely how you retrieve lists of customers.

  • Coupling auth logic to the model: Models should focus solely on data persistence and relationships. Shoving Auth::user() directly into the model violates the single responsibility principle—now your model is handling both data access and authorization, making it harder to test, reuse, and update later.

  • Brittleness and missing functionality: The native get() method handles internal logic like eager loading, query constraints, and option parsing. Your override ignores all that, which could break existing code that relies on those features.

  • Hard to scale: If you need this same role-based filtering for other models (like Order or Invoice), you’d have to duplicate this code across every model—leading to messy, inconsistent code as your app grows.

A better approach: Use Eloquent Scopes

Laravel provides query scopes specifically for this kind of reusable, context-aware filtering. They keep your authorization logic separated from the model’s core data responsibilities and integrate seamlessly with Eloquent’s query builder.

Option 1: Local Scope (explicitly apply when needed)

Define a local scope in your Customer model to encapsulate the role-based logic:

public function scopeForCurrentUser($query)
{
    $user = auth()->user();
    
    // Handle unauthenticated users (adjust this rule to fit your app)
    if (!$user) {
        return $query->whereRaw('1=0');
    }

    match($user->role_id) {
        1 => $query, // Admin: return all records without filters
        4 => $query->where('user_id', $user->id), // Regular user: only their own customers
        3 => $query->where(function ($q) use ($user) {
            // Get IDs of users under this manager first
            $subordinateIds = User::where('user_id', $user->id)->pluck('id');
            $q->where('user_id', $user->id)->orWhereIn('user_id', $subordinateIds);
        }),
        default => $query->whereRaw('1=0') // Catch-all for unhandled roles
    };

    return $query;
}

Use it anywhere in your app like this:

// Fetch customers filtered by the current user's role
$customers = Customer::forCurrentUser()->get();

Option 2: Global Scope (automatically apply to all queries)

If you want this filter to apply every time you query the Customer model (unless explicitly disabled), use a global scope:

protected static function booted()
{
    static::addGlobalScope('current_user_filter', function ($query) {
        $user = auth()->user();
        
        if (!$user) {
            $query->whereRaw('1=0');
            return;
        }

        match($user->role_id) {
            1 => null, // No filter for admins
            4 => $query->where('user_id', $user->id),
            3 => $query->where(function ($q) use ($user) {
                $subordinateIds = User::where('user_id', $user->id)->pluck('id');
                $q->where('user_id', $user->id)->orWhereIn('user_id', $subordinateIds);
            }),
            default => $query->whereRaw('1=0')
        };
    });
}

To bypass the scope for specific queries (e.g., an admin dashboard that needs all records):

$allCustomers = Customer::withoutGlobalScope('current_user_filter')->get();

Final Takeaway

Your original approach might work in a test environment, but it’s not robust or maintainable for a real-world app. Query scopes are the idiomatic Laravel way to handle this kind of role-based data filtering—keeping your code clean, reusable, and aligned with the framework’s design.

内容的提问来源于stack exchange,提问作者Cem Flav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:53:45