Reputation: 1168
I have a database seeder where I want to seed a Topic
table. These are saved per Organization
. The name of the Topic
is a key
. For each Organization
there are multiple Topics
, and sometimes an array
with the same names could be inserted. To avoid this error:
Integrity constraint violation: 1062 Duplicate entry
I am using the firstOrCreate
option from Eloquent
. It looks for the organization_id
and the name
. If they don't exist together yet, it should insert a record, else it should skip inserting the record.
public function run($organizationId, $topicName)
{
$this->disableForeignKeys();
$topic = Topic::allTenants()
->firstOrCreate([
'organization_id' => $organizationId,
'name' => $topicName,
], [
'description' => 'Not used',
]);
$this->enableForeignKeys();
return $topic->id;
}
But when I insert a Topic
, with an unused organization_id
it gives me the error that the record already exist. But that isn't the case because the organization_id
and name
don't exist in the database yet. So why does it give me this error? It looks like it isn't even checking for both organization_id
and name
.
These are the Schemas for the Topics table:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class TopicsUniqueFields extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('topics', function (Blueprint $table) {
$table->unique(['organisation_id', 'name']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('topics', function (Blueprint $table) {
$table->dropUnique(['organisation_id', 'name']);
});
}
}
The one above sets the unique fields for the Topics table.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateTopicsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('topics', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('organisation_id');
$table->string('name');
$table->text('description')->nullable();
$table->timestamps();
$table->foreign('organisation_id')
->references('id')->on('organisations');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('topics');
}
}
Upvotes: 1
Views: 746
Reputation: 2045
Is is definitely the organization_id
or name
fields that are duplicated, do you have any other unique fields on your table?
The only other think I could think of is Topic::allTenants()
method limiting the scope of the query? i.e. Topics exist with the organization_id
or name
field that are out of scope of the query.
Upvotes: 1