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

如何在Laravel Inertia JS中利用用户角色关联获取角色用户数

问题描述

我在Laravel+Inertia+Vue项目中遇到了以下问题:

  • User模型关联Role的代码:
public function role() {
    return $this->belongsTo(Role::class);
}
  • Role模型中写了一个计算用户数量的方法:
public function count() {
    return User::where('role_id', $this->id)->count();
}
  • 在Tinker中调用$role->count()能正常返回对应角色的用户数(比如ID为1的角色返回1),但在Vue组件中无法获取这个值。
  • Vue组件代码:
<li v-for="role in roles">Role name: {{ role.name }}</li>
<li>Role count: {{ role.count}}</li>
  • RoleController传递数据的代码:
public function index()
{
    return Inertia::render('Roles/Index', [
        'roles' => Role::all(),
    ]);
}

期望的显示效果是:

Role name: Administrator
Role count: 1

Role name: Subscriber
Role count: 5

解决方案

问题核心是后端模型的自定义方法不会被序列化到前端,前端只能拿到模型对应数据库表的字段,所以需要把用户数量转为可序列化的属性传递。

方法一:使用Eloquent的withCount(推荐)

这是Laravel官方推荐的关联计数方式,更高效且符合ORM规范。

  1. 在Role模型中定义与User的关联关系:
public function users() {
    return $this->hasMany(User::class);
}
  1. 修改控制器,预加载用户计数:
public function index()
{
    return Inertia::render('Roles/Index', [
        'roles' => Role::withCount('users')->get(),
    ]);
}
  1. 前端直接访问生成的users_count属性:
<div v-for="role in roles" :key="role.id">
    <p>Role name: {{ role.name }}</p>
    <p>Role count: {{ role.users_count }}</p>
    <hr>
</div>

方法二:使用访问器

如果不想定义关联,也可以通过访问器把计算结果转为模型属性:

  1. 在Role模型中添加访问器:
public function getUserCountAttribute() {
    return User::where('role_id', $this->id)->count();
}
  1. (可选)如果希望每次序列化模型都自动带上这个属性,在Role模型中添加:
protected $appends = ['user_count'];

或者在控制器中手动追加:

public function index()
{
    return Inertia::render('Roles/Index', [
        'roles' => Role::all()->append('user_count'),
    ]);
}
  1. 前端访问user_count属性:
<div v-for="role in roles" :key="role.id">
    <p>Role name: {{ role.name }}</p>
    <p>Role count: {{ role.user_count }}</p>
    <hr>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 07:10:26