【问题标题】:Laravel - Retrieve pivot relationshipLaravel - 检索枢轴关系
【发布时间】:2020-08-23 22:42:55
【问题描述】:

我有以下数据库架构:

users
    id

skills
    id

skill_user
    id
    user_id
    skill_id

endorsements
    id
    skill_user_id

Laravel 模型定义如下:

class User extends Authenticatable
{
    public function skills()
    {
        return $this
            ->belongsToMany('App\Skill')
            ->using(SkillUser::class)
            ->withPivot('endorsements_count')
            ->orderBy('endorsements_count', 'desc');
    }

}

class Skill extends Model
{
    public function users()
    {
        return $this
            ->belongsToMany('App\User')
            ->using(SkillUser::class)
            ->withPivot('user_id');
    }
}

class SkillUser extends Pivot
{
    public function endorsements()
    {
        return $this->hasMany('App\Endorsement', 'skill_user_id', 'id');
    }
}

class Endorsement extends Model
{
    public function skill_user() {
        return $this->belongsTo('App\SkillUser');
    }
}

从上面可以看出,user 可以通过名为SkillUser 的多对多表连接多个skills。此外,每个用户的技能都可以得到其他用户的认可 (endorsement)。 endorsements 在数据透视表上加入(每个 user_skill 可以有多个背书)。

现在我正试图弄清楚如何在 Laravel (Eloquent) 中构建一个查询,该查询将获取具有他所有技能的用户,并且对于每项技能,所有它都是在单个查询中的认可。

当我执行以下操作时:

User::with('skills')->findOrFail(1)->skills[0]->pivot->endorsements

它正确返回了用户和技能信息,但是枢轴(UserSkill)内部的背书是空的。此外,当我检查枢轴->关系时,它也是空的。

另一方面,如果我这样查询:

SkillUser::where('id', '=', 1)->first()->endorsements

我得到了所有的认可,所以我猜这种关系设置正确。我想我错过了以某种方式将“背书”专门包含在数据透视表中。

任何帮助将不胜感激!

【问题讨论】:

  • 只是为了确定;这是你想要的“类似”回应吗? prnt.sc/se54b6
  • 是的,差不多就是这样。

标签: laravel eloquent


【解决方案1】:
class Skill extends Model
{
    public function endorsements()
    {
        return $this->hasMany(Endorsement::class, 'skill_user_id');
    }
}
class Endorsement extends Model
{
    public function user()
    {
        return $this->hasOne(User::class, 'id', 'user_id')->select(['id', 'firstname', 'lastname']);
    }
}
class User extends Model
{
    public function skills()
    {
        return $this->belongsToMany(Skill::class)->using(SkillUser::class)->select(['skill_user.id']);
    }
}

我将endorser 列添加到endorsements 表以与用户关联。

return User::with('skills.endorsements.user')->findOrFail(1, ['id', 'name']);

它会打印这样的东西;

{
  "id": 1,
  "name": "my-user",
  "skills": [
    {
      "id": 1,
      "name": "askill",
      "pivot": {
        "user_id": 1,
        "skill_id": 1
      },
      "endorsements": [
        {
          "id": 1,
          "skill_user_id": 1,
          "endorser": 2,
          "user": {
            "id": 2,
            "name": "user-2"
          }
        },
        {
          "id": 2,
          "skill_user_id": 1,
          "endorser": 3,
          "user": {
            "id": 3,
            "name": "user-3"
          }
        }
      ]
    },
    {
      "id": 2,
      "name": "bskill",
      "pivot": {
        "user_id": 1,
        "skill_id": 2
      },
      "endorsements": [
        {
          "id": 3,
          "skill_user_id": 2,
          "endorser": 2,
          "user": {
            "id": 2,
            "name": "user-2"
          }
        }
      ]
    },
    {
      "id": 4,
      "name": "dskill",
      "pivot": {
        "user_id": 1,
        "skill_id": 4
      },
      "endorsements": []
    }
  ]
}

这里是在后台执行的查询;

SELECT `id`, `name`
FROM `users`
WHERE `users`.`id` = '1'
LIMIT 1;

SELECT `skills`.*, `skill_user`.`user_id` as `pivot_user_id`, `skill_user`.`skill_id` as `pivot_skill_id`
FROM `skills`
         inner join `skill_user` on `skills`.`id` = `skill_user`.`skill_id`
WHERE `skill_user`.`user_id` in ('1');

SELECT *
FROM `endorsements`
WHERE `endorsements`.`skill_user_id` in ('1', '2', '4');

SELECT `id`, `name`
FROM `users`
WHERE `users`.`id` in ('2', '3');

【讨论】:

  • 你确定这会正确加入表格吗 - $this->hasMany(Endorsement::class, 'skill_user_id'); ?我的意思是它是否有一些 Laravel 约定,它知道它需要加入 SkillUser 表,即使它是从 Skill 模型完成的?
  • @Adam 我在答案后面附加了执行的查询。
  • 我终于开始测试它,但它似乎不起作用。大多数技能都缺少背书。知道为什么会这样吗?
  • @Adam 我通过使用样本数据对其进行了测试。 prnt.sc/se6ecw 你可以从这里看到; skill_user 表用于usersskills - endorsements 用于skill_useruser 表之间。
  • 我用一些测试数据制作了一个数据库转储:textuploader.com/1c4kw 例如,如果您查看 Skill_user 表,ID 为 7 的记录,它应该有一个 ID 为 118 的背书 - 来自用户(背书者) id 1. 您的解决方案不返回此背书。知道为什么会这样吗?
猜你喜欢
  • 2019-07-05
  • 2018-05-16
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
相关资源
最近更新 更多