Comprehensive checklist and prevention strategies for common Ruby on Rails errors. Use this skill BEFORE writing any Rails code to prevent ViewComponent template errors, ActiveRecord query mistakes, method exposure issues, N+1 queries, and other common Rails pitfalls. Trigger keywords: errors, bugs, security, validation, prevention, pitfalls, debugging, exceptions, error handling
Provides preventative checklists and error patterns for common Rails mistakes. Use this skill BEFORE writing any Rails code to prevent ViewComponent template errors, ActiveRecord query mistakes, method exposure issues, N+1 queries, and other common pitfalls.
/plugin marketplace add Kaakati/rails-enterprise-dev/plugin install reactree-rails-dev@manifest-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
This skill provides preventative checklists and error patterns for common Rails mistakes. Review relevant sections BEFORE writing code.
This is the #1 cause of runtime errors in Rails applications.
WRONG ASSUMPTION: Service has method → View can call it through component
CORRECT RULE: Service has method + Component exposes it = View can call it
# Step 1: List all methods view will call on component
grep -oE '@[a-z_]+\.[a-z_]+' app/views/{path}/*.erb | sort -u
# Step 2: List all public methods in component
grep -E '^\s+def [a-z_]+' app/components/{component}_component.rb
# Step 3: Compare - any view call without component method = BUG
# Missing methods MUST be added to component BEFORE writing view code
# Pattern 1: Delegation
class Metrics::DashboardComponent < ViewComponent::Base
delegate :calculate_lifetime_tasks,
:calculate_lifetime_success_rate,
to: :@service
def initialize(service:)
@service = service
end
end
# Pattern 2: Wrapper methods (preferred for transformation)
class Metrics::DashboardComponent < ViewComponent::Base
def initialize(service:)
@service = service
end
def lifetime_tasks
@service.calculate_lifetime_tasks
end
def lifetime_success_rate
@service.calculate_lifetime_success_rate
end
end
# Pattern 3: Expose service directly (use sparingly)
class Metrics::DashboardComponent < ViewComponent::Base
attr_reader :service
def initialize(service:)
@service = service
end
end
# View then calls: dashboard.service.calculate_lifetime_tasks
Error Pattern:
Couldn't find a template file or inline render method for {Component}
Root Causes:
Prevention Checklist:
# Before creating component:
ls app/components/ # Check structure
head -50 app/components/*_component.rb | head -1 # Review existing pattern
# Verify naming: ComponentName -> component_name/
Required Files:
app/components/{namespace}/{component_name}_component.rb
app/components/{namespace}/{component_name}_component.html.erb
Correct Patterns:
# Option A: Separate template file
# app/components/metrics/kpi_card_component.rb
class Metrics::KpiCardComponent < ViewComponent::Base
def initialize(title:, value:)
@title = title
@value = value
end
end
# app/components/metrics/kpi_card_component.html.erb
# <div class="kpi-card">
# <h3><%= @title %></h3>
# <span><%= @value %></span>
# </div>
# Option B: Inline template (call method)
class Metrics::KpiCardComponent < ViewComponent::Base
def initialize(title:, value:)
@title = title
@value = value
end
def call
content_tag :div, class: "kpi-card" do
safe_join([
content_tag(:h3, @title),
content_tag(:span, @value)
])
end
end
end
Error Pattern:
undefined local variable or method '{method}' for an instance of {Component}
Did you mean `helpers.{method}`?
Root Cause: Calling view helper directly without helpers. prefix
Prevention Rules:
helpers.method_name for any Rails helperHelpers Requiring Prefix:
# WRONG # CORRECT
link_to(...) helpers.link_to(...)
image_tag(...) helpers.image_tag(...)
url_for(...) helpers.url_for(...)
form_with(...) helpers.form_with(...)
number_to_currency(...) helpers.number_to_currency(...)
time_ago_in_words(...) helpers.time_ago_in_words(...)
truncate(...) helpers.truncate(...)
pluralize(...) helpers.pluralize(...)
content_tag(...) helpers.content_tag(...)
tag(...) helpers.tag(...)
content_for(...) helpers.content_for(...)
Alternative - Delegate Helpers:
class Metrics::KpiCardComponent < ViewComponent::Base
delegate :number_to_currency, :link_to, to: :helpers
def formatted_value
number_to_currency(@value) # Now works without prefix
end
end
Error Pattern:
content is not defined
Prevention: Always check content? before using content
<% if content? %>
<%= content %>
<% end %>
Error Pattern:
PG::GroupingError: ERROR: column "{table}.{column}" must appear in the GROUP BY clause
Root Causes:
.select with .group but including non-grouped columnsincludes/preload) with GROUP BY.pluck or .select with associations and GROUP BYPrevention Rules:
includes/preload/eager_load with GROUP BY.select only for grouped columns and aggregatesExamples:
# WRONG - selecting all columns with group
Task.includes(:user).group(:task_type).count
# This tries to select tasks.* which fails
# WRONG - selecting id with group
Task.select(:task_type, :id).group(:task_type).count
# id is not grouped or aggregated
# CORRECT - only select grouped columns and aggregates
Task.group(:task_type).count
# => { "type_a" => 5, "type_b" => 3 }
# CORRECT - explicit select with only valid columns
Task.select(:task_type, 'COUNT(*) as count').group(:task_type)
# CORRECT - if you need associated data, query separately
type_counts = Task.group(:task_type).count
tasks_by_type = type_counts.keys.each_with_object({}) do |type, hash|
hash[type] = Task.where(task_type: type).includes(:user).limit(5)
end
# CORRECT - using pluck for simple aggregations
Task.group(:task_type).pluck(:task_type, 'COUNT(*)')
# => [["type_a", 5], ["type_b", 3]]
Before Writing GROUP BY Query:
# Detection command
grep -r '\.group(' app/ --include='*.rb' -A3 -B3
grep -r '\.includes.*\.group\|.group.*\.includes' app/ --include='*.rb'
Detection: Multiple queries for same association in logs
Prevention:
# WRONG - N+1
tasks.each { |t| puts t.user.name }
# CORRECT
tasks.includes(:user).each { |t| puts t.user.name }
Error Pattern:
PG::AmbiguousColumn: ERROR: column reference "{column}" is ambiguous
Prevention: Always qualify columns when joining
# WRONG
User.joins(:tasks).where(status: 'active') # Both have status?
# CORRECT
User.joins(:tasks).where(users: { status: 'active' })
# OR
User.joins(:tasks).where('users.status = ?', 'active')
Error Pattern:
ActiveModel::MissingAttributeError: missing attribute: {attribute}
Prevention: Include all attributes needed downstream
# WRONG - later code needs 'email'
users = User.select(:id, :name)
users.each { |u| puts u.email } # ERROR!
# CORRECT
users = User.select(:id, :name, :email)
Error Pattern:
ActionView::MissingTemplate
Prevention:
# Before creating controller action:
ls app/views/{controller}/
Error Pattern:
AbstractController::ActionNotFound
Root Causes:
# Verification
rails routes | grep {controller}
grep -n 'def ' app/controllers/{controller}_controller.rb
Error Pattern:
undefined method '{method}' for nil:NilClass
Prevention Patterns:
# Safe navigation
user&.profile&.settings&.theme
# Guard clause
return unless user&.profile
# With default
user&.profile&.settings&.theme || 'default'
# Early return
def process_user(user)
return if user.nil?
# ... rest of method
end
Error Pattern:
ArgumentError: wrong number of arguments (given X, expected Y)
Prevention:
# Before modifying method signature
grep -r 'method_name' app/ --include='*.rb'
# Update all call sites
Rules:
[ ] Check app/components/ structure
[ ] Review existing component for template pattern (inline vs file)
[ ] Verify naming: Namespace::ComponentNameComponent
[ ] Create both .rb AND .html.erb files (unless using inline)
[ ] List ALL methods view will need
[ ] Implement ALL needed methods in component
[ ] Prefix ALL Rails helpers with 'helpers.' or delegate them
[ ] List ALL methods view will call on component
[ ] For EACH method, verify it exists in component class
[ ] If method missing, ADD to component BEFORE view code
[ ] Verify underlying service/model has implementation
[ ] List ALL columns in SELECT
[ ] Verify each is in GROUP BY or aggregate function
[ ] Remove includes/preload/eager_load
[ ] Test query in rails console first
[ ] Qualify ambiguous columns with table name
[ ] Consider if includes is better for the use case
[ ] View exists for non-redirect actions?
[ ] Routes point to public methods?
[ ] All @variables view needs are set?
[ ] Inspect existing similar implementations
[ ] Check naming conventions in codebase
[ ] Verify all dependencies exist (gems, files, routes)
[ ] Verify method exposure across all layers (view→component→service)
# Find where method is called
grep -r 'method_name' app/ --include='*.rb'
# Find method definition
grep -rn 'def method_name' app/ --include='*.rb'
# Check method visibility
grep -B5 'def method_name' app/path/to/file.rb
# List component methods
grep -E '^\s+def [a-z_]+' app/components/path_component.rb
# List service methods
grep -E '^\s+def [a-z_]+' app/services/path.rb
# Compare view calls vs component methods
grep -oE '@\w+\.\w+' app/views/path/*.erb | sort -u
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
This skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
This 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.