👉 Go to Summary
There is no wrong or right way, there is our way.
-- Someone
.
.
.
Models
- It should represent primarily ORM mapping.
- It does not contain use cases, see actions.
- It can have small helper methods, computed properties, or
scopes
to make it easy to query data.
class User extends Model{
// Relationships
function country(): BelongsTo { ... }
// Helper method
function isAdmin(): bool { ... }
// Query scope
function scopeActive(Builder $query) { ... }
// Computed attribute
function getShortNameAttribute(): string { ... }
}
Migrations
- Use normalized modeling.
- Stick with convention
xxxx_id
forFKs
. - Comment edge case columns.
- Remember
indexes
(performance).
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->foreignId('country_id')->constrained();
$table->string('name')->index();
$table->string('cpf')->comment('Brazilian social number');
});
Seeders
- Must contain all default values to bootstrap app first time.
- Mostly it represents domain business value that should be mapped into model constants.
- Remember seeders can run many times, so put a
IF
.
class PaymentTypesSeeder extends Seeder
{
public function run()
{
// Avoid run twice
if (PaymentType::count()) {
return;
}
// Insert initial data when app bootstraps
PaymentType::insert([...])
}
}
Factories
- If it matters use a pre-seeded value.
- If it does not matter call a factory.
class UserFactory extends Factory
{
public function definition()
{
return [
// It is a well known value, should be one from seeder
'prefered_payment_type_id' => PaymentType::inRandomOrder()->first(),
// does not matter who is the parent user
'parent_id' => User::factory(),
'name' => $this->faker->name(),
// ....
];
}
Top comments (0)