
vanilla-rails-delegated-types
by ZempTime
SKILL.md
name: vanilla-rails-delegated-types description: Use when designing content systems where 5+ distinct types need to comingle in feeds, timelines, or searches with shared metadata and operations - NOT for simple polymorphic associations or 1-3 similar types
Delegated Types (Recording/Recordable Pattern)
A container model (Recording) unifies many content types (Recordables) that share metadata, access control, and operations.
Core insight: When many content types must comingle and share behavior, create a unified container rather than duplicating metadata or using complex polymorphic queries.
When to Use
digraph decision {
"How many content types?" [shape=diamond];
"Do they comingle in UI?" [shape=diamond];
"Share metadata/operations?" [shape=diamond];
"Direct associations" [shape=box];
"Delegated types" [shape=box];
"Consider merging types" [shape=box];
"How many content types?" -> "Direct associations" [label="1-2"];
"How many content types?" -> "Do they comingle in UI?" [label="3-4"];
"How many content types?" -> "Share metadata/operations?" [label="5+"];
"Do they comingle in UI?" -> "Consider merging types" [label="rarely"];
"Do they comingle in UI?" -> "Share metadata/operations?" [label="often"];
"Share metadata/operations?" -> "Direct associations" [label="no"];
"Share metadata/operations?" -> "Delegated types" [label="yes"];
}
Use when:
- 5+ content types (Messages, Documents, Uploads, Comments, etc.)
- Types appear together in feeds, timelines, activity streams
- Shared metadata: project, creator, timestamps, access control
- Common operations: copy, move, archive, search across all types
- Single query needed: "all content in project X sorted by date"
Don't use when:
- Only 1-3 types (use direct associations)
- Types are similar enough to merge (see flattening.md)
- Types don't comingle in UI
- No shared metadata or operations
Quick Reference
| Decision | Answer |
|---|---|
| 1-2 content types | Direct associations |
| 3-4 types, rarely comingle | Consider merging or direct |
| 3-4 types, often comingle | Maybe delegated types |
| 5+ types, shared metadata | Delegated types |
| Only 1 type left | Flatten (see flattening.md) |
| Container adds no value | Flatten |
Difference from Simple Polymorphic
| Aspect | Simple Polymorphic | Delegated Types |
|---|---|---|
| Query target | Each concrete type | Recording (container) |
| Shared metadata | Duplicated in each table | Once in Recording |
| Pagination | Complex (merge in Ruby) | Natural (query Recording) |
| Access control | Per-type | On Recording |
Sub-Documents
- implementing.md - Two-layer pattern (Bucket + Recording), schema, models, querying
- flattening.md - When to remove delegated types, PR 445 example, signals
Real-World Usage
Basecamp uses this for: Messages, Documents, Uploads, Comments, Todos - unified project timeline with shared access control and operations.
Fizzy removed it: When only Comments remained after merging EventSummary (see flattening.md).
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon