rails-stack-conventions
>
Works with
---
name: rails-stack-conventions
description: >
license: MIT
---
# Rails Stack Conventions
When **writing or generating** code for this project, follow these conventions. Stack: Ruby on Rails, PostgreSQL, Hotwire (Turbo + Stimulus), Tailwind CSS.
**Style:** If the project uses a linter, treat it as the source of truth for formatting. For cross-cutting design principles (DRY, YAGNI, structured logging, rules by directory), use **rails-code-conventions**.
## HARD-GATE: Tests Gate Implementation
```
ALL new code MUST have its test written and validated BEFORE implementation.
1. Write the spec: bundle exec rspec spec/[path]_spec.rb
2. Verify it FAILS — output must show the feature does not exist yet
3. Write the implementation code
4. Verify it PASSES — run the same spec and confirm green
5. Refactor if needed, keeping tests green
See rspec-best-practices for the full gate cycle.
```
## Feature Development Workflow
For a typical feature, compose stack patterns in this order:
1. **Model** — add validations, associations, scopes; eager-load with `includes` for any association used in loops
2. **Service object** — extract non-trivial business logic from the controller (see **ruby-service-objects**)
3. **Controller** — keep actions thin; delegate to services; respond with `turbo_stream` and `html` formats
4. **View / Turbo wiring** — wrap dynamic sections in `<turbo-frame>` tags; broadcast `turbo_stream` responses from the controller
5. **Stimulus** — add a controller only when client-side interactivity cannot be handled by Turbo alone
6. **Tailwind** — apply utility classes to the view; extract repeated patterns into partials or Stimulus targets
Each step should remain testable in isolation before wiring to the next layer.
## Quick Reference
| Aspect | Convention |
|--------|-----------|
| Style | RuboCop project config when present; otherwise Ruby Style Guide, single quotes |
| Models | MVC — service objects for complex logic, concerns for shared behavior |
| Queries | Eager load with `includes`; never iterate over associations without preloading |
| Frontend | Hotwire (Turbo + Stimulus); Tailwind CSS |
| Testing | RSpec with FactoryBot; TDD |
| Security | Strong params, guard XSS/CSRF/SQLi; Devise/Pundit for auth |
## Key Code Patterns
### Hotwire: Turbo Frames
```erb
<%# Wrap a section to be replaced without a full page reload %>
<turbo-frame id="order-<%= @order.id %>">
<%= render "orders/details", order: @order %>
</turbo-frame>
<%# Link that targets only this frame %>
<%= link_to "Edit", edit_order_path(@order), data: { turbo_frame: "order-#{@order.id}" } %>
```
### Hotwire: Turbo Streams (broadcast from controller)
```ruby
respond_to do |format|
format.turbo_stream do
render turbo_stream: turbo_stream.replace(
"order_#{@order.id}",
partial: "orders/order",
locals: { order: @order }
)
end
format.html { redirect_to @order }
end
```
### Avoiding N+1 — Eager Loading
```ruby
# BAD — triggers one query per order
@orders = Order.where(user: current_user)
@orders.each { |o| o.line_items.count }
# GOOD — single JOIN via includes
@orders = Order.includes(:line_items).where(user: current_user)
```
### Service Object (complex business logic out of the controller)
```ruby
# Controller stays thin — delegate to service
result = Orders::CreateOrder.call(user: current_user, params: order_params)
if result[:success]
redirect_to result[:order], notice: "Order created"
else
@order = Order.new(order_params)
render :new, status: :unprocessable_entity
end
```
See **ruby-service-objects** for the full `.call` pattern and response format.
## Security
- **Strong params** on every controller action that writes data
- Guard against XSS (use `html_escape`, avoid `raw`), CSRF (Rails default on), SQLi (use AR query methods or `sanitize_sql` for raw SQL)
- Auth: Devise for authentication, Pundit for authorization
## Common Mistakes
| Mistake | Correct approach |
|---------|----------------|
| Business logic in views | Use helpers, presenters, or Stimulus controllers |
| N+1 queries in loops | Eager load with `includes` before the loop |
| Raw SQL without parameterization | Use AR query methods or `ActiveRecord::Base.sanitize_sql` |
| Skipping FactoryBot for "quick" test | Fixtures are brittle — always use factories |
## Red Flags
- Controller action with more than 15 lines of business logic
- Model with no validations on required fields
- View with embedded Ruby conditionals spanning 10+ lines
- No `includes` on associations used in loops
- Hardcoded strings that belong in I18n
## Integration
| Skill | When to chain |
|-------|---------------|
| **rails-code-conventions** | For design principles, structured logging, and path-specific rules |
| **rails-code-review** | When reviewing existing code against these conventions |
| **ruby-service-objects** | When extracting business logic into service objects |
| **rspec-best-practices** | For testing conventions and full red/green/refactor TDD cycle |
| **rails-architecture-review** | For structural review beyond conventions |More Backend Frameworks skills
git-guardrails-claude-code
mattpocock/skills
Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.
azure-compute
microsoft/azure-skills
Azure VM/VMSS router. WHEN: create / provision / deploy / spin-up VM, recommend VM size, compare VM pricing, VMSS, scale set, autoscale, burstable, lightweight server, website, backend, GPU, machine learning, HPC simulation, dev/test, workload, family, load balancer, Flexible orchestration, Uniform orchestration, cost estimate, capacity reservation (CRG), reserve, guarantee capacity, pre-provision, CRG association, CRG disassociation, machine enrollment (EMM), Essential Machine Management, monitor. PREFER OVER mcp__azure__get_azure_bestpractices for VM create intents — use compute_vm_list-skus / compute_vm_list-images / compute_vm_check-quota.
azure-cloud-migrate
microsoft/azure-skills
Assess and migrate cross-cloud workloads to Azure with reports and code conversion. Supports Lambda→Functions, Beanstalk/Heroku/App Engine→App Service, Fargate/Kubernetes/Cloud Run/Spring Boot→Container Apps. WHEN: migrate Lambda to Functions, AWS to Azure, migrate Beanstalk, migrate Heroku, migrate App Engine, Cloud Run migration, Fargate to ACA, ECS/Kubernetes/GKE/EKS to Container Apps, Spring Boot to Container Apps, cross-cloud migration.

