Declare fullName or commentCount once as SQL on the model and it behaves like a column everywhere — sortable, selectable, never stale. And Wheels 4's select=false + includeCalculated pair fixes the cost problem calculated properties always created: expensive expressions run only where they're asked for, additively.
findAll on 400,000 rows materializes everything into memory at once — and the request cache holds it there. Wheels 4's findEach and findInBatches walk big result sets a page at a time, with three built-in optimizations you'd forget to hand-roll and two sharp edges worth knowing first.
A comprehensive Wheels 4.0 guide to model associations — hasMany, belongsTo, and hasOne, the exact dynamic methods each one generates, dependent-delete cascades, nested properties from form params, eager loading with include=, has-many-through, and polymorphic associations — with the sharp edges that bite in practice.
A practical Wheels 4.0 guide to the full validation surface — conditional rules with condition/unless/when, custom validate() methods, enum() integration, and how to read the error API correctly. Built end-to-end around one User model, with every behavior grounded in the framework source.
Wheels 4.0 ships three model-side features that compose into one design: scopes name reusable query fragments, enums turn property values into auto-generated checkers and scopes, and the chainable query builder swaps raw WHERE strings for fluent, type-aware composition. This post walks all three through one worked example and surfaces the bug I hit while writing it.