Jan 15, 2025
3
Level 2
Eloquent manyToMany relationship fails on SQL
I have been struggling to make this happen, but every time I failed.
I have two models - Map and User, and both can have many Maps (or users, respectively). The thing is, map has a primary key slug, while User has primary key id and I want to create a pivot table that connects these two models. Here is what I got so far:
Schemes:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('password')->nullable();
$table->enum('role', \App\Enum\Role::toArray());
$table->timestamps();
});
Schema::create('maps', function (Blueprint $table) {
$table->string('name');
$table->string('slug')->primary();
$table->string('perex')->nullable();
$table->string('categories')->nullable();
$table->enum('company', \App\Enum\Company::toArray());
$table->string('icon')->nullable();
$table->boolean('is_public')->default(false);
$table->boolean('bounds')->default(false);
$table->timestamps();
});
Schema::create('map_user', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
$table->string('map_slug');
$table->foreign('map_slug')->references('slug')->on('maps');
});
Map.php
class Map extends Model
{
protected $primaryKey = 'slug';
protected $keyType = 'string';
protected $fillable = [
'name',
'slug',
'perex',
'categories',
'company',
'icon',
'is_public',
'bounds',
];
public function suppliers(): Collection
{
return $this->hasMany(Supplier::class)->get();
}
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'map_user', 'map_slug', 'user_id');
}
}
User.php
class User extends Model
{
use HasFactory;
protected $fillable = [
'name',
'email',
'password',
];
public function maps(): BelongsToMany
{
return $this->belongsToMany(Map::class, 'map_user', 'user_id', 'map_slug');
}
}
When creating a new Map, I want to attach the user to it:
/**
* Store a newly created resource in storage.
*/
public function store(StoreMapRequest $request): RedirectResponse
{
$user = User::where('email', auth()->user()->getAuthIdentifier())->firstOrFail();
$map = Map::create([
'name' => $request->input('name'),
'slug' => $request->input('slug'),
'perex' => $request->input('perex'),
'categories' => $request->input('categories'),
'company' => $request->enum('company', Company::class),
'icon' => $request->input('icon'),
'is_public' => $request->boolean('isPublic'),
'bounds' => $request->boolean('bounds'),
]);
$map->users()->attach($user->id);
return to_route('admin.dashboard')->with('success', 'Map created!');
}
and on the ->attach() method I get following error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`mapy-dek`.`map_user`, CONSTRAINT `map_user_map_slug_foreign` FOREIGN KEY (`map_slug`) REFERENCES `maps` (`slug`))
insert into
`map_user` (`map_slug`, `user_id`)
values
(0, 1)
Thank you for your help!
Please or to participate in this conversation.