Model Generation
Generate Doctrine ORM entity models with three different approaches: simple generation, interactive wizard, or quick CLI syntax. Choose the method that fits your workflow.
Three Ways to Create Models
ZephyrPHP offers three commands for model generation, each suited to different scenarios:
| Command | Best For | Complexity |
|---|---|---|
make:model |
Simple models, quick scaffolding | Low |
model:wizard |
Complex models, interactive building | Medium to High |
model:build |
Quick one-liners, scripting | Medium |
make:model - Simple Model Generation
Create a basic Doctrine ORM entity model with standard id, timestamps, and any additional fields you specify.
php craftsman make:model [name] [fields]
Arguments
| Argument | Type | Description |
|---|---|---|
name |
Required | Model name in PascalCase (e.g., User, BlogPost) |
fields |
Optional | Comma-separated field definitions (name:type) |
Examples
# Basic model with just id and timestamps
php craftsman make:model Product
# Model with custom fields
php craftsman make:model User name:string,email:string,age:integer
# Model with various field types
php craftsman make:model Post title:string,content:text,published:boolean,views:integer
Supported Field Types
| Type | Database Type | PHP Type | Example |
|---|---|---|---|
string |
VARCHAR(255) | string | name:string |
text |
TEXT | string | content:text |
integer |
INT | int | age:integer |
boolean |
TINYINT(1) | bool | active:boolean |
datetime |
DATETIME | DateTime | publishedAt:datetime |
decimal |
DECIMAL(10,2) | float | price:decimal |
json |
JSON | array | metadata:json |
What Gets Generated
A model file is created at src/Models/ModelName.php with:
- Doctrine ORM
#[Entity]annotation - Auto-incrementing
idfield created_atandupdated_attimestamps- All specified custom fields with appropriate types
- Getter and setter methods for all properties
- Proper namespace and imports
Example Generated Model
<?php
namespace App\Models;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\GeneratedValue;
#[Entity]
#[Table(name: 'products')]
class Product
{
#[Id]
#[GeneratedValue]
#[Column(type: 'integer')]
private int $id;
#[Column(type: 'string', length: 255)]
private string $name;
#[Column(type: 'decimal', precision: 10, scale: 2)]
private float $price;
#[Column(type: 'datetime')]
private \DateTime $createdAt;
#[Column(type: 'datetime')]
private \DateTime $updatedAt;
public function __construct()
{
$this->createdAt = new \DateTime();
$this->updatedAt = new \DateTime();
}
// Getters and setters...
}
Common Use Cases
Quick Prototyping
# Rapidly create multiple simple models
php craftsman make:model Category name:string
php craftsman make:model Tag name:string,slug:string
php craftsman make:model Comment content:text,approved:boolean
Basic CRUD Resources
# Create a simple model then build CRUD around it
php craftsman make:model Article title:string,content:text
php craftsman make:crud Article
model:wizard - Interactive Model Builder
An interactive wizard that guides you through creating complex models with relationships, indexes, constraints, and advanced field options.
php craftsman model:wizard
Functionality
- Step-by-step interactive prompts
- Define unlimited fields with detailed configuration
- Configure relationships (OneToMany, ManyToOne, ManyToMany)
- Set up indexes and unique constraints
- Customize field lengths, nullable status, defaults
- Preview generated code before saving
Example Wizard Session
$ php craftsman model:wizard
ZephyrPHP Model Wizard
======================
Model name (PascalCase): User
Add fields to your model
------------------------
Field name (or 'done' to finish): name
Field type [string]: string
Length [255]: 100
Nullable? [no]: no
✓ Added field: name (string, length: 100)
Field name (or 'done' to finish): email
Field type [string]: string
Length [255]: 255
Nullable? [no]: no
Unique? [no]: yes
✓ Added field: email (string, length: 255, unique)
Field name (or 'done' to finish): bio
Field type [string]: text
Nullable? [no]: yes
✓ Added field: bio (text, nullable)
Field name (or 'done' to finish): age
Field type [string]: integer
Nullable? [no]: yes
✓ Added field: age (integer, nullable)
Field name (or 'done' to finish): done
Add relationships
-----------------
Add a relationship? [yes/no]: yes
Relationship type [ManyToOne/OneToMany/ManyToMany]: OneToMany
Related entity: Post
Mapped by: user
✓ Added relationship: posts (OneToMany → Post)
Add another relationship? [yes/no]: no
Summary
-------
Model: User
Fields: name, email, bio, age
Relationships: posts (OneToMany → Post)
Create this model? [yes/no]: yes
✓ Model created: src/Models/User.php
Advanced Features
Field Configuration Options
- Type: string, text, integer, boolean, datetime, decimal, json
- Length: Custom length for string fields
- Nullable: Allow NULL values
- Unique: Enforce unique constraint
- Default: Set default value
- Precision/Scale: For decimal fields
Relationship Types
| Type | Use Case | Example |
|---|---|---|
OneToMany |
One parent has many children | User has many Posts |
ManyToOne |
Many children belong to one parent | Post belongs to User |
ManyToMany |
Many-to-many relationship | Post has many Tags, Tag has many Posts |
OneToOne |
One-to-one relationship | User has one Profile |
When to Use the Wizard
Complex Models
# Models with many fields and relationships
php craftsman model:wizard
# Create User with name, email, password, profile, posts, comments
Learning Doctrine
# Interactive prompts teach you Doctrine features
php craftsman model:wizard
# Learn about annotations, relationships, constraints
Team Collaboration
# Guided process ensures consistency
php craftsman model:wizard
# All team members create models the same way
model:build - Quick CLI Syntax
Create models with a concise CLI syntax, perfect for one-liners and scripting. More powerful than make:model, faster than model:wizard.
php craftsman model:build [name] [definition]
Arguments
| Argument | Type | Description |
|---|---|---|
name |
Required | Model name in PascalCase |
definition |
Required | Field definitions with modifiers |
Definition Syntax
fieldName:type:modifiers
Available modifiers:
nullable- Allow NULL valuesunique- Enforce unique constraintindex- Create index on fieldlength:N- Set custom length (string fields)default:value- Set default value
Examples
# Basic model with modifiers
php craftsman model:build User \
name:string:length:100 \
email:string:unique \
bio:text:nullable \
age:integer:nullable
# E-commerce product model
php craftsman model:build Product \
name:string:length:200 \
sku:string:unique:index \
price:decimal \
stock:integer:default:0 \
active:boolean:default:true \
description:text:nullable
# Blog post model
php craftsman model:build Post \
title:string:length:255 \
slug:string:unique:index \
content:text \
excerpt:text:nullable \
published:boolean:default:false \
views:integer:default:0 \
publishedAt:datetime:nullable
Advanced Usage
Multiple Modifiers
# Field can have multiple modifiers
php craftsman model:build Category \
name:string:unique:index:length:100 \
slug:string:unique:index:length:100 \
description:text:nullable \
active:boolean:default:true
Complex Data Types
# JSON and decimal types
php craftsman model:build Order \
total:decimal:default:0.00 \
items:json \
metadata:json:nullable \
status:string:default:pending:length:50
Scripting and Automation
#!/bin/bash
# Create multiple models in a script
php craftsman model:build User name:string:unique email:string:unique
php craftsman model:build Post title:string content:text
php craftsman model:build Comment content:text approved:boolean:default:false
# Generate schema
php craftsman db:schema
model:build vs model:wizard
| Feature | model:build | model:wizard |
|---|---|---|
| Speed | Fast (one command) | Slower (interactive) |
| Fields | Unlimited | Unlimited |
| Modifiers | Via syntax | Via prompts |
| Relationships | Not supported | Fully supported |
| Scripting | Excellent | Difficult |
| Learning curve | Medium | Low |
Choosing the Right Command
Use make:model When...
- You need a simple model quickly
- You're prototyping or learning
- You don't need relationships or constraints
- You'll manually edit the model afterward
Use model:wizard When...
- You're creating a complex model with relationships
- You want guidance through the process
- You need to configure indexes and constraints
- You're new to Doctrine ORM
- You want to see a preview before creating
Use model:build When...
- You know exactly what you need
- You're scripting or automating
- You want a concise, one-line command
- You don't need relationships (add manually later)
- You're comfortable with CLI syntax
After Creating Models
Update Database Schema
# Always run after creating/modifying models
php craftsman db:schema
Add Relationships Manually
If you used make:model or model:build, add relationships by editing the model file:
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
#[OneToMany(mappedBy: 'user', targetEntity: Post::class)]
private Collection $posts;
public function __construct()
{
$this->posts = new ArrayCollection();
// ... existing constructor code
}
public function getPosts(): Collection
{
return $this->posts;
}
Customize the Model
Add custom methods, validation, or business logic:
public function getFullName(): string
{
return $this->firstName . ' ' . $this->lastName;
}
public function isAdmin(): bool
{
return in_array('ROLE_ADMIN', $this->roles);
}
public function publish(): void
{
$this->published = true;
$this->publishedAt = new \DateTime();
}
Best Practices
Naming Conventions
- Model names: PascalCase, singular (User, BlogPost, OrderItem)
- Field names: camelCase (firstName, createdAt, isActive)
- Table names: snake_case, plural (users, blog_posts, order_items)
- Foreign keys: singular_id (user_id, post_id, order_id)
Choosing Field Types
| Data | Type | Reason |
|---|---|---|
| Short text (< 255 chars) | string |
Indexed, fast searches |
| Long text (> 255 chars) | text |
No length limit |
| True/false | boolean |
Efficient storage |
| Whole numbers | integer |
Fast calculations |
| Money, precise decimals | decimal |
No rounding errors |
| Dates with time | datetime |
Timezone support |
| Arrays, objects | json |
Structured data |
Model Organization
src/Models/
├── User.php
├── Post.php
├── Comment.php
├── Category.php
├── Tag.php
└── Traits/
├── Timestampable.php
└── SoftDeletable.php
Troubleshooting
Model File Not Created
# Check src/Models directory exists
mkdir -p src/Models
# Check permissions
chmod 755 src/Models
Namespace Errors
Ensure your composer.json has proper autoloading:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
# Regenerate autoloader
composer dump-autoload
Schema Not Created
# Verify database connection
php craftsman db:test
# Ensure database module is installed
php craftsman add database
# Generate schema
php craftsman db:schema
Next Steps
Now that you can create models:
- Generate database tables with Database Commands
- Build complete CRUD apps with Code Generation
- Learn about Working with Models in your application
- Return to Craftsman CLI Overview