skills/rails-model-patterns/SKILL.md
Analyzes and recommends ActiveRecord model patterns including associations, validations, scopes, callbacks, migrations, and query optimization. Use when designing models, reviewing schema, adding associations (has_many, belongs_to), writing validations, creating scopes, or planning migrations. NOT for controller logic, routing, view rendering, or service object design.
npx skillsauth add ag0os/rails-dev-plugin rails-model-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Analyze and recommend ActiveRecord model patterns for well-structured Rails applications.
Where a model's domain logic and side effects belong forks on Axis A — logic placement:
rails-stack-profiles (Axis A — native or extracted).native → decomposition.native.mdextracted → decomposition.extracted.mdDefault to native if the axis cannot be resolved. Everything else in this file is invariant.
:dependent: Prevent orphaned records:inverse_of: Ensure bidirectional association consistencyFollow standard Rails model organization. Key ordering: constants, associations, validations, scopes, callbacks, class methods, instance methods, private methods. Generate standard ActiveRecord associations, validations, and scopes following Rails conventions.
Instead of a closed boolean, use a related model. Stores who, when, and why.
class Card < ApplicationRecord
has_one :closure, dependent: :destroy
def closed? = closure.present?
def close!(by:, reason: nil) = create_closure!(creator: by, reason: reason)
def reopen! = closure&.destroy!
end
class Closure < ApplicationRecord
belongs_to :card
belongs_to :creator, class_name: "User"
end
Reduce controller boilerplate using default: with lambdas:
class Post < ApplicationRecord
belongs_to :creator, class_name: "User", default: -> { Current.user }
belongs_to :account, default: -> { Current.account }
end
# Controller: @post = Post.create!(post_params) — no need to assign creator
# migration: add_column :users, :posts_count, :integer, default: 0, null: false
belongs_to :user, counter_cache: true
| Anti-Pattern | Problem | Fix |
|-------------|---------|-----|
| Fat models (500+ lines) | Hard to maintain | Decompose — see the decomposition guide for your axis |
| Callbacks with complex orchestration | Hard to reason about | Simplify the callback — see the decomposition guide for your axis |
| Missing :dependent on associations | Orphaned records | Always specify :dependent |
| default_scope | Confusing query behavior | Use named scopes instead |
| Validations without DB constraints | Data integrity gaps | Add both layers |
| Boolean flags for state | No audit trail, no metadata | Use state-as-relationship pattern (Closure, Pin, Triage models) |
When analyzing or creating models, provide:
project-conventions fingerprint (Minitest/RSpec, fixtures/factories); do not infer it from architecturesave (returns false) for user-facing forms; save! (raises) inside transactionsActiveRecord::Base.transactionActiveRecord::RecordInvalid, ActiveRecord::RecordNotFound, ActiveRecord::StaleObjectErrorlock_version) for concurrent updatesdevelopment
WHAT: Language-agnostic corrective guidance for the refactoring phase. WHEN: Agent is restructuring code, fixing code smells, reducing complexity, or improving maintainability. NOT FOR: Writing new features, debugging runtime errors, performance tuning, or object design decisions.
tools
Analyzes Rails view templates, partials, layouts, helpers, and form patterns for best practices. Use when reviewing ERB templates, improving view performance with fragment caching, fixing form helpers, organizing partials, adding accessibility attributes, or evaluating collection rendering. NOT for Stimulus/Turbo logic (use hotwire-patterns), controller concerns, or API-only responses.
testing
Analyzes Rails test suites and recommends testing best practices for RSpec and Minitest. Use when writing new tests, reviewing test coverage, fixing flaky tests, improving test performance, choosing between test types (unit, integration, system, request), or setting up factories and fixtures. NOT for production monitoring, deployment verification, or load/stress testing infrastructure.
development
Detects a Rails project's architecture axes — logic placement (native vs extracted) and delivery (html vs api) — so other skills load profile-appropriate guidance without inline conditionals. Use when planning architecture or when a recommendation depends on where business logic lives or whether the app renders HTML or serves JSON. NOT for test framework, job backend, cache store, or auth library choices — those are orthogonal facts detected by project-conventions.