General Principles
- Prefer explicit definitions over hidden magic
- Keep structure (models) separate from behavior (queries)
- Use migrations deliberately, never accidentally
- Review changes before applying them to production
Models
- Define one model per table
- Always define a primary key
- Keep models focused on structure only
- Avoid embedding query logic inside model definitions
- Bind database connections explicitly using
WithDB
Fields
- Use the most specific field type available
- Explicitly mark required fields using
NotNull() - Use
IsUnique()andIsIndex()intentionally - Prefer database defaults over application-side defaults
- Avoid overusing large text or blob fields
Queries
- Always use field references instead of raw column names
- Use
First()when expecting a single row - Paginate large result sets using
LimitorPage - Check errors after every database operation
- Avoid loading entire tables into memory
Schema Migration
- Use
--migrate-modelonly when schema changes are expected - Run schema migration in development, not automatically in production
- Review schema changes before deploying
- Keep schema changes small and incremental
Components
- Use components for authoritative, low-churn datasets
- Always define a primary key for component-backed models
- Review component sync behavior before using in production
- Use
--migrate-componentintentionally - Avoid using components for transactional or user-generated data
Environment Strategy
- Development: Use
-mmand-mcfreely - Staging: Validate migrations against real data
- Production: Disable automatic migrations
- Always back up production databases before changes
- Log and monitor migration output
Final Notes
ModelsHandler is designed to give you control. Used correctly, it enables rapid development without sacrificing clarity or safety.