Apeli
Apeli

Reputation: 529

Laravel pivot table relationships

I'm having serious trouble in wrapping my head around the Laravel relationships.

In my app there's Projects that have Tasks. I have ended up with a pivot table (which also has some extra columns):

CREATE TABLE `tasks_projects` (
`pivot_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`id` int(11) DEFAULT NULL,
`project_id` int(11) DEFAULT NULL,
`allocated_hours` int(11) DEFAULT NULL,
`display_order` int(11) DEFAULT NULL,
`hourly_price` int(3) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`pivot_id`)
)

This doesn't seem logical, as the 'id' column refers to a Task's id, and any direct updates to the pivot table go wrong because of that.

In \App\Project.php I have:

public function project_tasks() {
    return $this->hasManyThrough('\App\Task', '\App\TasksProjects', "project_id", "id");
}

In \App\Task.php I have:

public function projects() {
    return $this->belongsToMany('\App\Project', 'tasks_projects');
}

The $project->project_tasks() returns the correct tasks, and I thought I was all set - but now I tried to update the pivot table rows with $project->project_tasks()->updateExistingPivot, and all I get is

Call to undefined method Illuminate\Database\Query\Builder::updateExistingPivot()

Upvotes: 0

Views: 115

Answers (1)

user320487
user320487

Reputation:

With a many-to-many relationship you should be setting both related model's id on the pivot table:

CREATE TABLE `project_task` (
`project_id` int(11) DEFAULT NULL,
`task_id` int(11) DEFAULT NULL,
`allocated_hours` int(11) DEFAULT NULL,
`display_order` int(11) DEFAULT NULL,
`hourly_price` int(3) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`pivot_id`)
)

Eloquent naming conventions state the pivot table should be named using singular forms of the two related models in alphabetical order.

Both models will then define a belongsToMany relation:

public function projects() {
    return $this->belongsToMany('\App\Project');
}

public function tasks() {
    return $this->belongsToMany('\App\Task');
}

Upvotes: 1

Related Questions