如何使用 Laravel 中的 Eloquent 获取用户的 myProjects 任务
How to Get User's myProjects' Tasks with Eloquent in Laravel
我是 Laravel 和 Eloquent 的新手。
在我的应用程序中,我想检索当前用户和其他项目成员的任务并将它们显示在视图中。
这是我建立的数据库关系:
users
(id)
projects
(id, user_id)
user_project
(id, user_id, project_id, 角色)
tasks
(id, user_id, project_id)
(我已经在迁移中定义了所需的外键)
为了解释这种关系,每个项目都有一个用户(创建项目的人)。但是在 user_project
table 中,也可以将用户分配给其他项目,并在那里定义他们的角色。例如:有两个用户:
id=1
id=2
和三个项目:
id=1, user_id=1
id=2, user_id=2
id=3, user_id=1
user_project关系:
id=1, user_id=1, project_id=1, 角色=admin
id=2, user_id=2, project_id=1, 角色=雇员
id=3, user_id=2, project_id=2, 角色=admin
id=4, user_id=1, project_id=3, 角色=admin
还有四个任务:
id=1, user_id=1, project_id=1
id=2, user_id=2, project_id=1
id=3, user_id=1, project_id=2
id=4, user_id=1, project_id=3
我希望用户 id=2
能够看到 project_id=1
的任务,因为他作为员工被邀请到该项目以及 project_id=2
的任务,因为他创建了那个项目。当然,用户不应该看到 project_id=3 的任务,因为他不是会员。那么,最巧妙的方法是什么?
以下是我定义的模型:
class User extends Authenticatable
{
public function projects(){
return $this->hasMany(Project::class);
}
public function tasks(){
return $this->hasMany(Task::class);
}
public function joinedProjects()
{
return $this->hasMany(ProjectUser::class);
}
}
class Project extends Model
{
public function tasks(){
return $this->hasMany(Task::class);
}
public function users(){
return $this->hasMany(User::class);
}
}
class ProjectUser extends Model
{
}
class Task extends Model
{
public function projects(){
return $this->belongsTo(Project::class);
}
public function users(){
return $this->belongsTo(User::class);
}
}
这是我尝试检索项目成员任务的方法(我正在寻找的理想方法是:$tasks = $user->joinedProjects->tasks
但我不知道该怎么做,所以这是我目前正在尝试完成此操作的方法):
class TasksController extends Controller
{
public function index()
{
$user = Auth()->user();
//I guess there are better ways to retrieve projects, but:
$projects = app('App\Http\Controllers\HomeController')->allProjects($user);
foreach($projects as $project){
$tasks[] = Task::where('project_id', $project->id);
}
return view('tasks.index', compact(['tasks','user']));
//gives error: Property [id] does not exist on the Eloquent builder instance
//when I'm trying to get $task->id in a foreach loop.
}
}
这是家庭控制器(我需要 HomeController 中的 allProjects()
功能来实现其他一些 class 功能):
class HomeController extends Controller
{
function allProjects($user){
$projects = $user->projects;
$otherProjects = \App\ProjectUser::where('user_id',$user->id)->get();
foreach ($otherProjects as $project){
$projects[] = \App\Project::find($project->project_id);
}
return $projects;
}
}
首先,我认为您应该将 joinedProjects
设置为 many-to-many relationship,这样访问它会感觉更直接。
// in User model
public function joinedProjects()
{
// i'm assuming you want to always have access to the role property
return $this->belongsToMany(Project::class, 'user_project')->withPivot('role');
}
// in Project model
public function memberUsers()
{
return $this->belongsToMany(User::class, 'user_project')->withPivot('role');
}
有了这个关系,您应该可以调用 $user->joinedProjects
来获取用户已加入的项目列表。
要获取任务,当然可以调用joinedProjects
关系,像你设置的for循环一样循环遍历生成的项目。或者作为替代方案,您可以使用集合 class' pluck 方法。
class TasksController extends Controller
{
public function index()
{
// here I put load to eager load the project and task
$user = Auth()->user()->load('joinedProjects.tasks');
// OPTION 1: you can loop to get the tasks
$tasks = collect();
foreach($user->joinedProjects as $project){
$tasks = $tasks->merge($project->tasks);
}
// OPTION 2: or use pluck (must be eager loaded to work)
$tasks = $user->joinedProjects->pluck('tasks');
// $tasks should be unique here, but if it is not you can call the unique method of collection
$tasks = $tasks->unique('id');
return view('tasks.index', compact(['tasks','user']));
}
}
你分享的HomeController
也可以通过新的关系得到简化
class HomeController extends Controller
{
function allProjects($user){
// here i'm assuming user automatically joins a project when they create it
$projects = $user->joinedProjects;
return $projects;
}
}
这是对 unique method i use in the code and the lazy eager loading
的一些额外参考
我是 Laravel 和 Eloquent 的新手。 在我的应用程序中,我想检索当前用户和其他项目成员的任务并将它们显示在视图中。 这是我建立的数据库关系:
users
(id)
projects
(id, user_id)
user_project
(id, user_id, project_id, 角色)
tasks
(id, user_id, project_id)
(我已经在迁移中定义了所需的外键)
为了解释这种关系,每个项目都有一个用户(创建项目的人)。但是在 user_project
table 中,也可以将用户分配给其他项目,并在那里定义他们的角色。例如:有两个用户:
id=1
id=2
和三个项目:
id=1, user_id=1
id=2, user_id=2
id=3, user_id=1
user_project关系:
id=1, user_id=1, project_id=1, 角色=admin
id=2, user_id=2, project_id=1, 角色=雇员
id=3, user_id=2, project_id=2, 角色=admin
id=4, user_id=1, project_id=3, 角色=admin
还有四个任务:
id=1, user_id=1, project_id=1
id=2, user_id=2, project_id=1
id=3, user_id=1, project_id=2
id=4, user_id=1, project_id=3
我希望用户 id=2
能够看到 project_id=1
的任务,因为他作为员工被邀请到该项目以及 project_id=2
的任务,因为他创建了那个项目。当然,用户不应该看到 project_id=3 的任务,因为他不是会员。那么,最巧妙的方法是什么?
以下是我定义的模型:
class User extends Authenticatable
{
public function projects(){
return $this->hasMany(Project::class);
}
public function tasks(){
return $this->hasMany(Task::class);
}
public function joinedProjects()
{
return $this->hasMany(ProjectUser::class);
}
}
class Project extends Model
{
public function tasks(){
return $this->hasMany(Task::class);
}
public function users(){
return $this->hasMany(User::class);
}
}
class ProjectUser extends Model
{
}
class Task extends Model
{
public function projects(){
return $this->belongsTo(Project::class);
}
public function users(){
return $this->belongsTo(User::class);
}
}
这是我尝试检索项目成员任务的方法(我正在寻找的理想方法是:$tasks = $user->joinedProjects->tasks
但我不知道该怎么做,所以这是我目前正在尝试完成此操作的方法):
class TasksController extends Controller
{
public function index()
{
$user = Auth()->user();
//I guess there are better ways to retrieve projects, but:
$projects = app('App\Http\Controllers\HomeController')->allProjects($user);
foreach($projects as $project){
$tasks[] = Task::where('project_id', $project->id);
}
return view('tasks.index', compact(['tasks','user']));
//gives error: Property [id] does not exist on the Eloquent builder instance
//when I'm trying to get $task->id in a foreach loop.
}
}
这是家庭控制器(我需要 HomeController 中的 allProjects()
功能来实现其他一些 class 功能):
class HomeController extends Controller
{
function allProjects($user){
$projects = $user->projects;
$otherProjects = \App\ProjectUser::where('user_id',$user->id)->get();
foreach ($otherProjects as $project){
$projects[] = \App\Project::find($project->project_id);
}
return $projects;
}
}
首先,我认为您应该将 joinedProjects
设置为 many-to-many relationship,这样访问它会感觉更直接。
// in User model
public function joinedProjects()
{
// i'm assuming you want to always have access to the role property
return $this->belongsToMany(Project::class, 'user_project')->withPivot('role');
}
// in Project model
public function memberUsers()
{
return $this->belongsToMany(User::class, 'user_project')->withPivot('role');
}
有了这个关系,您应该可以调用 $user->joinedProjects
来获取用户已加入的项目列表。
要获取任务,当然可以调用joinedProjects
关系,像你设置的for循环一样循环遍历生成的项目。或者作为替代方案,您可以使用集合 class' pluck 方法。
class TasksController extends Controller
{
public function index()
{
// here I put load to eager load the project and task
$user = Auth()->user()->load('joinedProjects.tasks');
// OPTION 1: you can loop to get the tasks
$tasks = collect();
foreach($user->joinedProjects as $project){
$tasks = $tasks->merge($project->tasks);
}
// OPTION 2: or use pluck (must be eager loaded to work)
$tasks = $user->joinedProjects->pluck('tasks');
// $tasks should be unique here, but if it is not you can call the unique method of collection
$tasks = $tasks->unique('id');
return view('tasks.index', compact(['tasks','user']));
}
}
你分享的HomeController
也可以通过新的关系得到简化
class HomeController extends Controller
{
function allProjects($user){
// here i'm assuming user automatically joins a project when they create it
$projects = $user->joinedProjects;
return $projects;
}
}
这是对 unique method i use in the code and the lazy eager loading
的一些额外参考