I have the beginnings of a Laravel application with only two models: User and Project. There is a many-to-many relationship between Users and Projects, A single User can be working on many Projects, and a single Project can be worked on by many Users.
The problem I'm experiencing has manifested itself in two ways:
project_user
pivot table, linking references to the first entries of the users
and projects
tables: INSERT INTO project_user (user_id, project_id) VALUES (1, 1)
. I then boot up Tinker in order to test the relationship. Accessing all Projects through the User model works as expected: User::find(1)->projects
(returns a valid collection of Project models), however, the inverse relationship: Project::find(1)->users
returns an empty collection, when it should be returning the User model referenced in the pivot table.project_user
table like so:public function run()
{
$project = Project::first();
$admin = User::first();
if (isset($project) && isset($admin)) {
echo "Project: $project\n";
echo "User: $admin\n";
// FIXME: Why isn't this working?
$project->users()->attach($admin);
// The inverse below also fails for the same reason
// $admin->projects()->attach($project);
}
}
Which causes the seed file to fail with the error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'project_id' cannot be null (SQL: insert into
project_user (
created_at ,
project_id ,
updated_at ,
user_id ) values (2020-02-02 17:01:04, ?, 2020-02-02 17:01:04, 1))
I've scoured my code, as well as the internet looking for a solution, to no avail. The problem must either be some very tiny mistake in my code, improper use of some function, or invalid order of operations. It's clear to me that there must be a problem with the association on the Project side, but I've literally compared Users and Projects side-by-side at every step and I can't figure out what's wrong. I'll paste the relevant code sections below, and if there's any additional information or code I can provide, I'm more than happy to do so. Thanks in advance for your help!
class User extends Authenticatable
{
public $type;
// Here is the relationship to the Projects this User is working on
public function projects()
{
// SELECT * FROM project_user WHERE user_id = $user->id
return $this->belongsToMany(Project::class)->withTimestamps();
}
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
class Project extends Model
{
public $id;
public $name;
public $deleted_at;
// Here is the relationship to the Users working on this Project
public function users()
{
// SELECT * FROM project_user WHERE project_id = $project->id
return $this->belongsToMany(User::class)
->withTimestamps();
}
protected $fillable = [
'name',
];
protected $casts = [
'deleted_at' => 'datetime',
];
}
users
and projects
table migrations: public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->enum('type', ['admin', 'client', 'editor'])->default('client');
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->unique();
$table->integer('memberCount')->default(0)->nullable(false);
$table->timestamp('deleted_at')->nullable();
$table->timestamps();
});
}
project_user
migration that sets the references:public function up()
{
Schema::create('project_user', function(Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('project_id');
$table->timestamps();
$table->unique(['user_id', 'project_id']);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');
});
}
Try removing public $id;
from your Project
model (and the other redundant properties). With Eloquent, you don't need to declare the model properties that exist as columns in the backing table of the model. I believe what's happening is the $id
property on your Project
model is being called, which is null, because it is overriding the magic getter that Eloquent will provide for this column out of the box.
If you're declaring the properties on your model so your IDE picks them up, consider using the barryvdh/laravel-ide-helper package instead.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.