I’m new to laravel and trying to make two tables with a one (customer) to many(table) relation and a custom Foreign Key tables
.customer
(I can not change this)
The connection is over customers
.id
on tables
.customer
.
After Running php artisan migrate:fresh --seed
everything is created as expected. But tables
.customer
is always 0.
I don’t get any errors. And both tables are created correctly.
What do I miss?
Here are my settings:
Models:
Customers.php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Customers extends Model {
use HasFactory;
public function tables() {
return $this->hasMany(Tables::class, 'customer');
}
public $timestamps = false;
}
Tables.php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Tables extends Model {
use HasFactory;
public function customers() {
return $this->belongsTo(Customers::class, 'customer');
}
public $timestamps = false;
}
Migration:
customers
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
Schema::create('customers', function (Blueprint $table) {
$table->string('id', 6)->primary();
$table
->string('img', 23)
->nullable()
->default(null);
$table->tinyText('name');
$table->tinyInteger('active')->default(1);
$table->bigInteger('created'); // unix timestamp when created
$table
->bigInteger('status')
->nullable()
->default(null); // null not deleted / unix timestamp when deleted
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
Schema::dropIfExists('customers');
}
};
tables
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
Schema::create('tables', function (Blueprint $table) {
$table->string('id', 8)->primary();
$table->tinyText('number');
$table->string('customer', 6); // TODO: repalce with uuid
$table->bigInteger('created'); // unix timestamp when created
$table
->bigInteger('status')
->nullable()
->default(null); // null not deleted / unix timestamp when deleted
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
Schema::dropIfExists('tables');
}
};
Factories:
CustomersFactory.php
namespace DatabaseFactories;
use IlluminateDatabaseEloquentFactoriesFactory;
/**
* @extends IlluminateDatabaseEloquentFactoriesFactory<AppModelsCustomers>
*/
class CustomersFactory extends Factory {
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition() {
return [
'id' => $this->faker->unique()->regexify('[A-Za-z0-9]{6}'),
'name' => $this->faker->company(),
'active' => $this->faker->boolean(),
'created' => $this->faker->unixTime(),
'status' => $this->faker->boolean() ? null : $this->faker->unixTime(),
];
}
}
TablesFactory.php
namespace DatabaseFactories;
use AppModelsCustomers;
use IlluminateDatabaseEloquentFactoriesFactory;
/**
* @extends IlluminateDatabaseEloquentFactoriesFactory<AppModelsTables>
*/
class TablesFactory extends Factory {
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition() {
return [
'id' => $this->faker->unique()->regexify('[A-Za-z0-9]{8}'),
'number' => $this->faker->unique()->numberBetween(1, 1000),
'customer' => Customers::factory()->create()->id,
'created' => $this->faker->unixTime(),
'status' => $this->faker->boolean() ? null : $this->faker->unixTime(),
];
}
}
Seeders:
customersSeeder.php
namespace DatabaseSeeders;
use AppModelsCustomers;
use IlluminateDatabaseConsoleSeedsWithoutModelEvents;
use IlluminateDatabaseSeeder;
class CustomersSeeder extends Seeder {
/**
* Run the database seeds.
*
* @return void
*/
public function run() {
Customers::factory()
->count(10)
->hasTables(20)
->create();
}
}
TablesSeeder.php
namespace DatabaseSeeders;
use AppModelsTables;
use IlluminateDatabaseConsoleSeedsWithoutModelEvents;
use IlluminateDatabaseSeeder;
class TablesSeeder extends Seeder {
/**
* Run the database seeds.
*
* @return void
*/
public function run() {
//
}
}
DatabaseSeeder.php
namespace DatabaseSeeders;
// use IlluminateDatabaseConsoleSeedsWithoutModelEvents;
use IlluminateDatabaseSeeder;
class DatabaseSeeder extends Seeder {
/**
* Seed the application's database.
*
* @return void
*/
public function run() {
$this->call([CustomersSeeder::class]);
}
}
2
Answers
By inspecting your models, you are recommended to define the table name first.
And then you need to define fillable properties in order to mass assign your database, as the docs said.
Or if you want every column becomes fillable just add guarded attribute.
Your issue is that you did not tell each model that the
id
is not an integer, it is by default (check the source code).So add this to both models:
Read about that here.