I have these 3 tables:
clients
id - integer name - string
projects
id - integer client_id - integer name - string
tasks
id - integer project_id - integer name - string
related through the HasManyThrough relationship.
In the client table I have a column relating to the number of tasks relating to the projects of that specific client.
I want that when I click on the number of tasks, I am redirected to the view of the client related tasks. While when I click it shows me all the tasks, but I want, as already specified, the tasks related to the projects of that specific client.
How can I solve this problem?
VIEW:
<tr>
<th >ID</th>
<th >Name</th>
<th >Task</th>
</tr>
@foreach ($clients as $client)
<tr>
<td>{{ $client->id }}</td>
<td>{{ $client->name }}</td>
<td>
<a href="{{route('task.index'}" >{{
$client->tasks_count }}
</a>
</td>
@endforeach
Route:
Route::get('/task/index', [TaskController::class, 'index'])->name('task.index');
TaskController:
public function index()
{
$tasks = Task::all();
//dd($tasks);
return view('task.index', compact('tasks'));
}
Model Client
class Client extends Model
{
use HasFactory;
protected $fillable = [
'name'
];
public function projects()
{
return $this->hasMany(Project::class);
}
public function tasks()
{
return $this->hasManyThrough(Task::class, Project::class);
}
}
Model Project
class Project extends Model
{
use HasFactory;
protected $fillable = [
'name',
'client_id'
];
public function client()
{
return $this->belongsTo(Client::class);
}
public function tasks()
{
return $this->hasMany(Task::class);
}
}
Model Task
class Task extends Model
{
use HasFactory;
protected $fillable = [
'name',
'project_id'
];
public function project()
{
return $this->belongsTo(Project::class);
}
}
CodePudding user response:
Create new route:
Route::get('/client/{client}/tasks', ['as' => 'client.tasks', 'uses' => 'ClientController@tasks'])->name('client.tasks');
Add something like this to your view:
//Not sure if that is a right syntax to bind the id in the route, need to verify
<a href="{{ route('client.tasks', [$client->id]) }}" >
{{ $client->tasks_count }}
</a>
Or:
//Route
Route::get('/client/{client}/tasks', [ClientController::class, 'tasks'])->name('client.tasks');
//and view
<a href="{{ URL::to('/client/' . $client->id . '/tasks') }}" >
{{ $client->tasks_count }}
</a>
And controller:
public function tasks(Client $client)
{
$tasks = $client->tasks;
//return your view with tasks associated with this client
}
CodePudding user response:
As you have written
$tasks = Task::all();
All tasks!
You need to pass along the id of the client with the request, preferably with route model binding so that you get a client instance in the controller. Then you can load the tasks or the projects with tasks below them
public function index(Client $client)
{
$tasks = $client->tasks()->get();
//dd($tasks);
return view('task.index', compact('tasks'));
}
or with projects
{
$projects = $client->projects()->with('tasks')->get();
return view('task.index', compact('projects'));
}
In this second example, you get a collection of projects with the tasks inside, so you can then show a list of projects and a list of tasks for that project