|
| 1 | +# Enums |
| 2 | + |
| 3 | +Enums let you define a fixed set of allowed values for a model property. Wheels automatically generates boolean checker methods, query scopes, and inclusion validation for each enum. |
| 4 | + |
| 5 | +## Defining Enums |
| 6 | + |
| 7 | +Add enums in your model's `config()` function: |
| 8 | + |
| 9 | +```cfm |
| 10 | +component extends="Model" { |
| 11 | + function config() { |
| 12 | + // String list — each value is both the name and stored value |
| 13 | + enum(property="status", values="draft,published,archived"); |
| 14 | +
|
| 15 | + // Struct mapping — names map to different stored values |
| 16 | + enum(property="priority", values={low: 0, medium: 1, high: 2}); |
| 17 | + } |
| 18 | +} |
| 19 | +``` |
| 20 | + |
| 21 | +### String List |
| 22 | + |
| 23 | +When you pass a comma-delimited string, each value serves as both the display name and the stored database value: |
| 24 | + |
| 25 | +```cfm |
| 26 | +enum(property="status", values="draft,published,archived"); |
| 27 | +// Stores "draft", "published", or "archived" in the database |
| 28 | +``` |
| 29 | + |
| 30 | +### Struct Mapping |
| 31 | + |
| 32 | +When you pass a struct, the keys are the names and the values are what gets stored in the database: |
| 33 | + |
| 34 | +```cfm |
| 35 | +enum(property="priority", values={low: 0, medium: 1, high: 2}); |
| 36 | +// Stores 0, 1, or 2 in the database |
| 37 | +``` |
| 38 | + |
| 39 | +## What Enums Generate |
| 40 | + |
| 41 | +Defining an enum automatically creates three things: |
| 42 | + |
| 43 | +### 1. Boolean Checker Methods |
| 44 | + |
| 45 | +For each enum value, an `is<Value>()` method is generated on model instances: |
| 46 | + |
| 47 | +```cfm |
| 48 | +post = model("Post").findByKey(1); |
| 49 | +
|
| 50 | +post.isDraft(); // true or false |
| 51 | +post.isPublished(); // true or false |
| 52 | +post.isArchived(); // true or false |
| 53 | +``` |
| 54 | + |
| 55 | +### 2. Query Scopes |
| 56 | + |
| 57 | +Each enum value becomes a named scope you can chain: |
| 58 | + |
| 59 | +```cfm |
| 60 | +// Find all draft posts |
| 61 | +drafts = model("Post").draft().findAll(); |
| 62 | +
|
| 63 | +// Find all published posts, ordered by date |
| 64 | +published = model("Post").published().findAll(order="createdAt DESC"); |
| 65 | +
|
| 66 | +// Count archived posts |
| 67 | +archivedCount = model("Post").archived().count(); |
| 68 | +``` |
| 69 | + |
| 70 | +### 3. Inclusion Validation |
| 71 | + |
| 72 | +A `validatesInclusionOf` validation is automatically registered, preventing invalid values: |
| 73 | + |
| 74 | +```cfm |
| 75 | +post = model("Post").new(); |
| 76 | +post.status = "invalid_value"; |
| 77 | +post.valid(); // false — "invalid_value" is not in the enum |
| 78 | +
|
| 79 | +post.status = "published"; |
| 80 | +post.valid(); // true (assuming other validations pass) |
| 81 | +post.errorsOn("status"); // empty array |
| 82 | +``` |
| 83 | + |
| 84 | +The validation uses `allowBlank=true`, so blank/empty values are permitted unless you add a separate `validatesPresenceOf`. |
| 85 | + |
| 86 | +## Examples |
| 87 | + |
| 88 | +### Filtering by Enum Value |
| 89 | + |
| 90 | +```cfm |
| 91 | +// Using auto-generated scopes |
| 92 | +model("Post").published().findAll(page=1, perPage=25); |
| 93 | +
|
| 94 | +// Using standard WHERE clause |
| 95 | +model("Post").findAll(where="status = 'published'"); |
| 96 | +
|
| 97 | +// Using query builder |
| 98 | +model("Post").where("status", "published").get(); |
| 99 | +``` |
| 100 | + |
| 101 | +### Checking State in Views |
| 102 | + |
| 103 | +```cfm |
| 104 | +<cfif post.isPublished()> |
| 105 | + <span class="badge badge-success">Published</span> |
| 106 | +<cfelseif post.isDraft()> |
| 107 | + <span class="badge badge-warning">Draft</span> |
| 108 | +<cfelse> |
| 109 | + <span class="badge badge-secondary">Archived</span> |
| 110 | +</cfif> |
| 111 | +``` |
| 112 | + |
| 113 | +### Combining Scopes |
| 114 | + |
| 115 | +```cfm |
| 116 | +// Enum scopes compose with other scopes |
| 117 | +model("Post").published().recent().findAll(); |
| 118 | +``` |
0 commit comments