在laravel query builder中根据用户的技能以及匹配的技能选择用户

7rtdyuoh  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(390)

我想根据用户的技能在数据库中搜索他们。然后我想得到技能匹配的用户配置文件。

我的数据库迁移

用户

$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');

技能

$table->increments('id');
$table->string('name');

用户技能

$table->increments('id');
$table->unsignedInteger('user_id');
$table->unsignedInteger('skill_id');

这是我的models:-

用户.php

public function skill(){
    return $this->belongsToMany(Skill::class, 'user_skill');
}

用户和技能模型具有多对多关系。
现在,我编写了一个查询,根据用户的技能从“user”表中选择用户。我的问题看起来像this:-

$skills = ["HTML", "CSS", "JavaScript"];
$result = User::with('skill')
    ->join('user_skill', 'users.id','=','user_skill.user_id')
    ->join('skills', 'user_skill.skill_id', '=', 'skills.id')
    ->select('users.name as Name','users.id as UserId')
    ->selectRaw('COUNT(skills.id) as skill_count')
    ->whereIn('skills.name', $skills)
    ->groupBy('users.id')
    ->orderBy('skill_count', 'desc')
    ->get();

这个查询在经过一些f之后给出了以下结果ormatting:-

但我想得到用户,以及他们的技能。给定屏幕截图中的每个用户都有大约5种技能。with('skill')子句应该返回用户及其技能。但是当我把结果放到foreach循环中,

foreach($result as $r){
    print_r($r->skill);
}

技能字段为空。laravelwith()子句应该与用户一起注入技能,因为他们有多对多的关系。我做错什么了吗?感谢您的帮助。
注意:当我查询user::with('skill')->get()时,它返回所有具有技能的用户。所以,我想这里的关系绑定很好。
提前谢谢。

35g0bw71

35g0bw711#

我认为它是空的,因为您的查询似乎有一个拼写错误,而不是 with('skills') 你写的很有技巧,加入时你用了正确的列名。
所以要解决这个问题:

$result = User::with('skills')
    ->join('user_skill', 'users.id','=','user_skill.user_id')
    ->join('skills', 'user_skill.skill_id', '=', 'skills.id')
    ->select('users.name as Name','users.id as UserId')
    ->selectRaw('COUNT(skills.id) as skill_count')
    ->whereIn('skills.name', $skills)
    ->groupBy('users.id')
    ->orderBy('skill_count', 'desc')
    ->get();
db2dz4w8

db2dz4w82#

$users = User::whereHas('skills'=>function($query){
  $query->whereIn('name', ['css', 'html', 'javascript']);
})->withCount('skills')
->select('users.name as Name','users.id as UserId')
->groupBy('users.id')
->orderBy('skill_count', 'desc')
->get();

当您对结果进行分组时,我认为不需要join语句。你可以用上面简单的代码实现所有你想要的东西。另外,正如另一个用户所提到的,要注意拼写错误。

相关问题