I'm new to Laravel and Eloquent. In my app, I want to retrieve the current user's and other project members' tasks and show them in the view. Here's the database relation I have made:
users
(id)
projects
(id, user_id)
user_project
(id, user_id, project_id, role)
tasks
(id, user_id, project_id)
(I have defined the required foreign keys in migrations)
To explain the relation, each project has a user (who has created the project). But in the user_project
table, users can be assigned to other projects as well and their role is defined there. For example: There are two users:
id=1
id=2
And three projects:
id=1, user_id=1
id=2, user_id=2
id=3, user_id=1
user_project relationship:
id=1, user_id=1, project_id=1, role=admin
id=2, user_id=2, project_id=1, role=employee
id=3, user_id=2, project_id=2, role=admin
id=4, user_id=1, project_id=3, role=admin
And four tasks:
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
I want the user id=2
to be able to see tasks of project_id=1
because he is invited to that project as employee together with the tasks of project_id=2
because he has created that project. Of course the user shouldn't be able to see the tasks of project_id=3 because he's not a member. So, what's the neatest way to do this?
Here are the models I have defined:
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);
}
}
Here's the way I'm trying to retrieve tasks of my project members (the ideal way I'm looking for to do this is: $tasks = $user->joinedProjects->tasks
but I don't know how to do it, so here's how I'm currently trying to get this done):
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.
}
}
And here's the home controller (I need the allProjects()
function in HomeController for some other class functions):
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;
}
}
$user->projects( )->get( )
? – 4givN