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

Laravel框架下如何将Controller中的$id变量传递到Model?

How to Pass Controller's $id to Model's Relationship in Laravel

The core issue here is that eager loading relationships (via ->with()) doesn't support passing parameters directly to relationship methods—Laravel calls these methods without arguments by default. To fix this, we can keep your base relationship logic in the model and dynamically apply the $id filter directly in the controller's eager load closure.

Step 1: Update the User Model Relationship

First, modify your shares_load_more relationship to remove the $id parameter, keeping all your common constraints intact:

// MODEL (User.php)
public function shares_load_more()
{
    return $this->hasMany(Share::class, 'user_id', 'id')
        ->select('id', 'link_id', 'user_id', 'shared_in', 'content', 'created_at')
        ->take(2)
        ->orderBy('id', 'desc')
        ->where('type', '=', 0);
}

Step 2: Apply the $id Filter in the Controller's Eager Load

In your controller, use a closure inside the ->with() method to inject the $id parameter and add the additional where clause. Make sure to include the nested relationships (links.tag, links.page) as part of the eager load:

// CONTROLLER
public function user_load_more($id, $friendly_url) {
    $user = User::where('friendly_url', '=', $friendly_url)
        ->with([
            'shares_load_more' => function ($query) use ($id) {
                // Apply the dynamic ID filter here
                $query->where('id', '<', $id);
            },
            'shares_load_more.links.tag',
            'userProfile.get_following'
        ])
        ->with(['shares_load_more.links.page' => function ($query) {
            $query->select('id', 'name', 'friendly_url');
        }])
        ->orderBy('id', 'desc')
        ->first();

    return view("site.list.user.links", compact("user"));
}

Why This Works

  • The base relationship logic (select fields, limit, ordering, type filter) stays encapsulated in the model, keeping your code DRY.
  • The use ($id) statement in the closure lets you access the controller's $id parameter within the query builder context.
  • Eager loading still works as expected, loading all related data in a single query (or minimal queries) instead of triggering N+1 issues.

Alternative Approach (If You Prefer Model-Encapsulated Logic)

If you want to keep the $id filter logic in the model, you can create a custom method that extends the base relationship:

// MODEL (User.php)
public function shares_load_more_with_id($id)
{
    return $this->shares_load_more()->where('id', '<', $id);
}

Then in the controller, you can load this after fetching the user (note: this will run an additional query instead of eager loading):

// CONTROLLER
$user = User::where('friendly_url', '=', $friendly_url)
    ->with('shares_load_more.links.tag', 'userProfile.get_following')
    ->with(['shares_load_more.links.page' => function ($query) {
        $query->select('id', 'name', 'friendly_url');
    }])
    ->orderBy('id', 'desc')
    ->first();

// Load filtered shares using the model method
$filteredShares = $user->shares_load_more_with_id($id)->get();

// Pass both to the view
return view("site.list.user.links", compact("user", "filteredShares"));

The first approach (eager load with closure) is generally preferred for performance, as it avoids extra database queries.


内容的提问来源于stack exchange,提问作者Valter Sousa Cardoso

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:24:35