I am new to Laravel. I try to create model with one to one relation.
But when i go to test it, its give me error:
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity
constraint violation: 1452 Cannot add or update a child row: a foreign
key constraint fails (belajar_laravel_eloquent.wallets, CONSTRAINT
wallets_customer_id_foreignFOREIGN KEY (customer_id) REFERENCES
customers(id)) (Connection: mysql, SQL: insert intowallets
(amount,customer_id) values (5700000, 0))
What is wrong?
This is my table:
Schema::create('customers', function (Blueprint $table) {
$table->string('id', 100)->primary();
$table->string('name', 100);
$table->string('email', 100)->unique('customer_email');
});
Schema::create('wallets', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('customer_id', 100);
$table->bigInteger('amount')->default(0);
$table->foreign('customer_id')->on('customers')->references('id');
});
This My Model:
class Customer extends Model
{
public $timestamps = false;
public function wallet(): HasOne
{
return $this->hasOne(Wallet::class, 'customer_id', 'id');
}
}
This My Model:
class Wallet extends Model
{
public $timestamps = false;
public function customer(): BelongsTo
{
return $this->BelongsTo(Customer::class, 'customer_id', 'id');
}
}
This is my test:
public function testOneToOneQueryRelation()
{
$customer = new Customer();
$customer->id = 'Rinam';
$customer->name = 'Rinam';
$customer->email = 'RinamSayang@gmail.com';
$customer->save();
$wallet = new Wallet();
$wallet->amount = 5700000;
$customer->wallet()->save($wallet);
self::assertNotNull($wallet->customer_id);
}
>Solution :
The error is because you are not using auto-increment primary key and also key type string so in Customer Model set the following property
protected $keyType = 'string';
public $incrementing = false;
As per Document
If your model’s primary key is not an integer, you should define a
protected $keyType property on your model. This property should have a
value of stringEloquent assumes that the primary key is an incrementing integer
value, which means that Eloquent will automatically cast the primary
key to an integer. If you wish to use a non-incrementing or a
non-numeric primary key you must define a public $incrementing
property on your model that is set to false
Ref : Primary Keys