This skill should be used when the user is working in a Rails 7+ application and asks about "Rails conventions", "naming conventions", "Rails structure", "Hotwire patterns", "Turbo frames", "Stimulus controllers", "Rails directory structure", "Rails best practices", or needs guidance on idiomatic Rails patterns for production systems.
Provides Rails 7+ conventions for naming, directory structure, Hotwire patterns, and production best practices. Use when users ask about Rails conventions, naming, structure, Turbo frames, Stimulus controllers, or idiomatic patterns for production Rails applications.
/plugin marketplace add betamatt/claude-plugins/plugin install ruby-on-rails@betamatt-claude-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/api-conventions.mdreferences/hotwire-patterns.mdProduction-focused guidance for Rails 7+ conventions, naming patterns, directory structure, and modern frontend integration with Hotwire.
User, OrderItem, PaymentTransaction)users, order_items, payment_transactions)_id (user_id, order_id)categories_products, roles_users)UsersController, Api::V1::OrdersController)users_controller.rb, api/v1/orders_controller.rb)index, show, new, create, edit, update, destroyPrefer resourceful routes over custom routes:
# Production pattern
resources :orders do
resources :line_items, shallow: true
member do
post :cancel
post :refund
end
collection do
get :pending
end
end
# API versioning
namespace :api do
namespace :v1 do
resources :orders, only: [:index, :show, :create]
end
end
app/views/controller_name/action.html.erb_partial.html.erbapp/views/shared/_partial.html.erbapp/views/components/_button.html.erbapp/
├── assets/
│ └── stylesheets/
├── channels/ # ActionCable channels
├── controllers/
│ ├── concerns/ # Controller concerns
│ └── api/ # API controllers
├── helpers/
├── javascript/
│ └── controllers/ # Stimulus controllers
├── jobs/ # ActiveJob classes
├── mailers/
├── models/
│ └── concerns/ # Model concerns
├── views/
│ ├── layouts/
│ ├── shared/
│ └── components/ # View components (if using)
config/
├── initializers/
├── locales/
└── environments/
db/
├── migrate/
└── seeds.rb
lib/
├── tasks/ # Rake tasks
└── templates/ # Generator templates
spec/ or test/
Place in app/services/ with clear naming:
# app/services/orders/create_service.rb
module Orders
class CreateService
def initialize(user:, cart:)
@user = user
@cart = cart
end
def call
# Implementation
end
end
end
# Usage: Orders::CreateService.new(user: current_user, cart: @cart).call
Place in app/queries/:
# app/queries/orders/pending_query.rb
module Orders
class PendingQuery
def initialize(relation = Order.all)
@relation = relation
end
def call
@relation.where(status: :pending)
.where("created_at > ?", 24.hours.ago)
.includes(:line_items, :user)
end
end
end
Use for partial page updates without full navigation:
<%# Index page with inline editing %>
<%= turbo_frame_tag "orders" do %>
<% @orders.each do |order| %>
<%= turbo_frame_tag dom_id(order) do %>
<%= render order %>
<% end %>
<% end %>
<% end %>
<%# Edit form that replaces the frame %>
<%= turbo_frame_tag dom_id(@order) do %>
<%= render "form", order: @order %>
<% end %>
Use for real-time updates and multi-element updates:
# Controller action
def create
@order = Order.create(order_params)
respond_to do |format|
format.turbo_stream
format.html { redirect_to orders_path }
end
end
<%# create.turbo_stream.erb %>
<%= turbo_stream.prepend "orders", @order %>
<%= turbo_stream.update "order_count", Order.count %>
Naming convention: controller-name_controller.js
// app/javascript/controllers/dropdown_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["menu"]
static values = { open: Boolean }
toggle() {
this.openValue = !this.openValue
}
openValueChanged() {
this.menuTarget.classList.toggle("hidden", !this.openValue)
}
}
<div data-controller="dropdown" data-dropdown-open-value="false">
<button data-action="click->dropdown#toggle">Menu</button>
<div data-dropdown-target="menu" class="hidden">
<!-- Menu content -->
</div>
</div>
# Edit credentials
bin/rails credentials:edit
# Environment-specific
bin/rails credentials:edit --environment production
Access pattern:
Rails.application.credentials.dig(:aws, :access_key_id)
Rails.application.credentials.stripe[:secret_key]
# config/environments/production.rb
Rails.application.configure do
config.force_ssl = true
config.log_level = :info
config.active_job.queue_adapter = :sidekiq
end
Name by feature, not gem:
# config/initializers/stripe.rb (not payments.rb)
Stripe.api_key = Rails.application.credentials.stripe[:secret_key]
def order_params
params.require(:order).permit(
:shipping_address_id,
:notes,
line_items_attributes: [:id, :product_id, :quantity, :_destroy]
)
end
Avoid callback chains for business logic. Prefer service objects:
# Avoid
class Order < ApplicationRecord
after_create :send_confirmation, :update_inventory, :notify_warehouse
end
# Prefer
class Orders::CreateService
def call
Order.transaction do
order = Order.create!(params)
OrderMailer.confirmation(order).deliver_later
Inventory::DeductService.new(order).call
Warehouse::NotifyJob.perform_later(order.id)
order
end
end
end
Define commonly used queries as scopes:
class Order < ApplicationRecord
scope :recent, -> { where("created_at > ?", 30.days.ago) }
scope :pending, -> { where(status: :pending) }
scope :with_items, -> { includes(:line_items) }
scope :for_user, ->(user) { where(user: user) }
end
For detailed patterns and examples:
references/hotwire-patterns.md - Advanced Turbo and Stimulus patternsreferences/api-conventions.md - API versioning, serialization, authentication patternsThis skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.