rails error prevention

Rails Error Prevention Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "rails error prevention" with this command: npx skills add kaakati/rails-enterprise-dev/kaakati-rails-enterprise-dev-rails-error-prevention

Rails Error Prevention Skill

This skill provides preventative checklists and error patterns for common Rails mistakes. Review relevant sections BEFORE writing code.

When to Use This Skill

  • Before creating ViewComponents

  • Before writing ActiveRecord queries with GROUP BY or joins

  • Before writing view code that calls component methods

  • Before creating controller actions

  • When debugging undefined method errors

  • When debugging template not found errors

  • When debugging ActiveRecord grouping errors

Critical Rule: Method Exposure Verification

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

Verification Process

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

Patterns to Fix Missing Methods

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

ViewComponent Errors

Template Not Found

Error Pattern:

Couldn't find a template file or inline render method for {Component}

Root Causes:

  • Missing template file (component.html.erb)

  • Template in wrong location

  • Class name doesn't match file path

  • Using render without inline template defined

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

Helper Method Errors

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:

  • ViewComponents do NOT have direct access to view helpers

  • Must use helpers.method_name for any Rails helper

Helpers 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

Content Block Errors

Error Pattern:

content is not defined

Prevention: Always check content? before using content

<% if content? %> <%= content %> <% end %>

ActiveRecord Errors

Grouping Error (PostgreSQL)

Error Pattern:

PG::GroupingError: ERROR: column "{table}.{column}" must appear in the GROUP BY clause

Root Causes:

  • SELECT includes columns not in GROUP BY or aggregate functions

  • Using .select with .group but including non-grouped columns

  • Eager loading (includes /preload ) with GROUP BY

  • Using .pluck or .select with associations and GROUP BY

Prevention Rules:

  • Every non-aggregated column in SELECT must be in GROUP BY

  • NEVER combine includes /preload /eager_load with GROUP BY

  • Use .select only for grouped columns and aggregates

  • If you need associated data with grouped results, query separately

Examples:

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'

N+1 Queries

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 }

Ambiguous Column

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')

Missing Attribute

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)

Controller Errors

Missing Template

Error Pattern:

ActionView::MissingTemplate

Prevention:

  • Every non-redirect action needs a view OR explicit render

  • View path must match controller namespace

Before creating controller action:

ls app/views/{controller}/

Unknown Action

Error Pattern:

AbstractController::ActionNotFound

Root Causes:

  • Route points to non-existent action

  • Action is private/protected (must be public)

Verification

rails routes | grep {controller} grep -n 'def ' app/controllers/{controller}_controller.rb

Nil Errors

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

Argument Errors

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:

  • Prefer keyword arguments for methods with 2+ params

  • Use default values for optional params

Prevention Checklists

Before Creating ViewComponent

[ ] 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

Before Writing View Code

[ ] 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

Before Writing ActiveRecord Query with GROUP BY

[ ] 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

Before Writing ActiveRecord Query with Joins

[ ] Qualify ambiguous columns with table name [ ] Consider if includes is better for the use case

Before Creating Controller Action

[ ] View exists for non-redirect actions? [ ] Routes point to public methods? [ ] All @variables view needs are set?

Before Any Code

[ ] 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)

Quick Debugging Commands

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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

flutter conventions & best practices

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

getx state management patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

ruby oop patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

rails localization (i18n) - english & arabic

No summary provided by upstream source.

Repository SourceNeeds Review