如何在Laravel中用口才来获取用户的myProjects任务

问题描述 投票:0回答:1

我是Laravel和Eloquent的新手。在我的应用程序中,我想检索当前用户和其他项目成员的任务,并将其显示在视图中。这是我建立的数据库关系:

users(id)

projects(ID,用户ID)

user_project(ID,用户ID,项目ID,角色)

tasks(ID,用户ID,项目ID)

((我已经定义了迁移中所需的外键)

为了解释这种关系,每个项目都有一个用户(创建该项目的用户)。但是在user_project表中,也可以将用户分配给其他项目,并在其中定义他们的角色。例如:有两个用户:id = 1id = 2

和三个项目:id = 1,user_id = 1id = 2,user_id = 2id = 3,user_id = 1

user_project关系:id = 1,user_id = 1,project_id = 1,role = adminid = 2,user_id = 2,project_id = 1,role = employeeid = 3,user_id = 2,project_id = 2,role = adminid = 4,user_id = 1,project_id = 3,role = admin

还有四个任务:id = 1,user_id = 1,project_id = 1id = 2,user_id = 2,project_id = 1id = 3,user_id = 1,project_id = 2id = 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 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;
    }
}
laravel eloquent many-to-many
1个回答
1
投票

首先,我认为您应该将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循环那样循环遍历生成的项目。或者,您也可以使用集合类的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中使用的lazy eager loading方法的一些附加参考信息>

© www.soinside.com 2019 - 2024. All rights reserved.