【问题标题】:Laravel model to get specific piece of dataLaravel 模型获取特定数据
【发布时间】:2020-12-22 00:00:45
【问题描述】:

我正在尝试创建一个函数来帮助我快速获取所需的数据。

通过所有的试验,我已经能够达到以下目标

表格

用户(ID、姓名)

项目(ID、名称)

User-Project (id, user_id, project_id, manager) 其中 manager 是一个布尔值,每个项目只能有一个经理(但员工仍然可以看到我们有数据透视表的项目原因,manager = 0 表示其他可以访问该项目的普通用户)

在我的项目模型中:

  public function Manager(){
    return $this->belongsToMany('App\User')->wherePivot('manager', true);
}

在我的视图中:

 <p><strong>Project Manager:</strong> {{$project->manager}}</p>

在我得到的实际页面上:

Project Manager: [{"id":4,"name":"Daniel Doe","email":"danieldoe@hotmail.com","phone":"70846556","email_verified_at":null,"created_at":"2020-12-20 21:05:50","updated_at":"2020-12-20 21:05:50","pivot":{"project_id":1,"user_id":4,"manager":1}}]

当我将视图更改为:

<p><strong>Project Manager:</strong> {{$project->manager[0]->name}}</p>

我明白了:

 Project Manager: Daniel Doe

这是我真正想要的,但如果可能的话,我想从模型中做到这一点。所以我尝试了:

public function Manager(){
    return $this->belongsToMany('App\User')->wherePivot('manager', true)->first()->name;
}

但我收到以下错误:

must return a relationship instance

这可以从模型的函数中完成吗?

【问题讨论】:

  • belongsToMany() 返回一个集合,即多条记录。您的函数名称应为 managers 以反映这一点。接下来,如果你的要求是“每个项目只能有一个经理”为什么要使用返回多个Manager的函数和数据库结构?应该是@ 987654330@,你的projects 表应该有一个manager_id,而不是它们之间的数据透视表......你的要求和编码不匹配。您仍然可以使用枢轴将users 链接到projects,但删除manager 列。
  • 因为项目可以有多个用户但只有一个经理,所以我编辑了问题,谢谢指出。
  • 是的,看我编辑的评论;您仍然可以拥有该关系的project_user 数据透视表,但它应该与manager 分开(无论如何我认为)。我可以看到两种方式的争论,但它有点偏离。我将发布如何使用您当前的结构的答案; 1 秒。

标签: laravel


【解决方案1】:

您可以保持您定义的关系,但要访问-&gt;first()-&gt;name,您需要使用“访问器”:

public function manager() {
  return $this->belongsToMany('App\User')->wherePivot('manager', true);
}

public function getManagerNameAttribute() {
  return $this->manager->first() ? $this->manager->first()->name : 'No Manager';
}

然后,在您的代码中,您可以简单地访问:

{{ $project->manager_name }}

如果您的 manager() 函数返回一个包含至少 1 条记录的集合,它将返回名称,否则将显示“无经理”作为后备。

【讨论】:

【解决方案2】:

如果您不想更改它的结构,可以使用访问器来获取此信息,大致如下:

class Project ...
{
    public function users()
    {
        return $this->belongsToMany(...)->withPivot(...);
    }

    public function getManagerAttribute()
    {
        return $this->users()->wherePivot('manager', 1)->first()?->name;
    }
}

您可以通过不同的方式执行此操作,您可以使用加载的 users 关系并使用 Collection 方法来过滤管理器。您可以创建另一个名为 managers 的关系,使用 wherePivot 关闭 users() 等...

使用此设置唯一需要担心的是每次调用 $model-&gt;manager 都会导致该查询,因此创建另一个关系 manager 可能是个好主意,这样您就可以加载一次并继续使用无需继续查询数据库:

public function managers()
{
    return $this->users()->wherePivot(...);
}

public function getManagerAttribute()
{
    return $this->managers->first()?->name;
}

不过,如前所述,最好在项目本身上添加 manager_id 之类的东西。

【讨论】:

  • 这绝对更干净。希望? null-safe 运算符在 PHP8 之前可用 :)
  • @TimLewis 是的,我已经把所有东西都移到了 PHP8 中,现在只能使用它......太多好的功能好友:)
  • 我希望我能;我阅读了“PHP8 中的新功能”页面,并在圣诞节像个孩子一样尖叫,但在我说服管理层转向它之前,我们被困在了 7 点。不过总有一天 :)
  • 只要我有至少 7.4 我会很高兴
猜你喜欢
  • 2019-04-02
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
相关资源
最近更新 更多