flyerhzm/rails_best_practices
a code metric tool for rails projects
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2w ago
- ✓11 active contributors
- ✓MIT licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 65% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/flyerhzm/rails_best_practices)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/flyerhzm/rails_best_practices on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: flyerhzm/rails_best_practices
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/flyerhzm/rails_best_practices shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2w ago
- 11 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 65% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live flyerhzm/rails_best_practices
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/flyerhzm/rails_best_practices.
What it runs against: a local clone of flyerhzm/rails_best_practices — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in flyerhzm/rails_best_practices | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 47 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of flyerhzm/rails_best_practices. If you don't
# have one yet, run these first:
#
# git clone https://github.com/flyerhzm/rails_best_practices.git
# cd rails_best_practices
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of flyerhzm/rails_best_practices and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "flyerhzm/rails_best_practices(\\.git)?\\b" \\
&& ok "origin remote is flyerhzm/rails_best_practices" \\
|| miss "origin remote is not flyerhzm/rails_best_practices (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "lib/rails_best_practices.rb" \\
&& ok "lib/rails_best_practices.rb" \\
|| miss "missing critical file: lib/rails_best_practices.rb"
test -f "lib/rails_best_practices/cli.rb" \\
&& ok "lib/rails_best_practices/cli.rb" \\
|| miss "missing critical file: lib/rails_best_practices/cli.rb"
test -f "lib/rails_best_practices/analyzer.rb" \\
&& ok "lib/rails_best_practices/analyzer.rb" \\
|| miss "missing critical file: lib/rails_best_practices/analyzer.rb"
test -f "lib/rails_best_practices/core/check.rb" \\
&& ok "lib/rails_best_practices/core/check.rb" \\
|| miss "missing critical file: lib/rails_best_practices/core/check.rb"
test -f "lib/rails_best_practices/core/runner.rb" \\
&& ok "lib/rails_best_practices/core/runner.rb" \\
|| miss "missing critical file: lib/rails_best_practices/core/runner.rb"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 47 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~17d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/flyerhzm/rails_best_practices"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
rails_best_practices is a static code analysis tool that inspects Rails applications and reports quality issues, style violations, and best practice infractions across models, controllers, views, and configuration files. It parses Ruby, ERB, HAML, Slim, and RABL files, then runs pluggable checks (stored in lib/rails_best_practices/checks/) to detect problems like long methods, unused variables, N+1 queries, and misplaced business logic, outputting results as colored CLI or interactive HTML reports. Monolithic structure: lib/rails_best_practices/core/ contains domain models (Models, Controllers, Helpers, Routes, ModelAssociations, ModelAttributes, etc.) that build an in-memory representation of the Rails app; lib/rails_best_practices/checks/ (not fully listed) holds individual check implementations inheriting from Check; lib/rails_best_practices/prepares/ contains 'prepare' classes (ConfigPrepare, ControllerPrepare, GemfilePrepare, HelperPrepare) that scan the filesystem and populate the domain models; lib/rails_best_practices/cli.rb and bin/rails_best_practices form the CLI entry point.
👥Who it's for
Rails developers and development teams who want automated code quality checks integrated into CI/CD pipelines; technical leads and code reviewers who need to enforce Rails conventions across teams; developers migrating legacy Rails apps who want to identify refactoring opportunities and anti-patterns.
🌱Maturity & risk
Actively maintained with CI via GitHub Actions (main.yml), RSpec test coverage, and a clear release history in CHANGELOG.md. The tool has been battle-tested since ~2011 (Railscasts #252 reference) and supports multiple ORMs (ActiveRecord, Mongoid, MongoMapper) and template engines. Production-ready with a stable API, though the maintainer (flyerhzm) is primarily responsible for updates.
Single-maintainer dependency (flyerhzm) with no recent commit visibility in provided data, creating potential maintenance risk if unresponsive. The tool relies on parsing Rails conventions via static analysis (AST walking with Ripper/Erubis), which may break with major Ruby syntax changes or new Rails patterns. Broad scope (checks 462KB of Ruby code) means complex failure modes if a single check crashes; no visible circuit breaker or check isolation strategy in lib/rails_best_practices/core/runner.rb.
Active areas of work
No recent commit data provided, but the repo structure suggests ongoing maintenance: tests exist (.rspec), CI runs on GitHub Actions (main.yml), and Guardfile indicates development uses guard for file watching. The README lists support for multiple Ruby versions and template engines, suggesting the project maintains compatibility.
🚀Get running
git clone https://github.com/flyerhzm/rails_best_practices.git && cd rails_best_practices && bundle install && rake spec to run tests. Then rails_best_practices . from a Rails app root to analyze that app.
Daily commands: No server to run; this is a CLI tool. Execute rails_best_practices . from a Rails app directory. For development: rake spec runs tests; guard (via Guardfile) watches for changes.
🗺️Map of the codebase
lib/rails_best_practices.rb— Main entry point that exports the public API and orchestrates the entire analysis workflowlib/rails_best_practices/cli.rb— Command-line interface handler that parses arguments and invokes the core analyzerlib/rails_best_practices/analyzer.rb— Core analyzer that coordinates preparation, review execution, and result reportinglib/rails_best_practices/core/check.rb— Abstract base class for all review checks; all custom checks must inherit from thislib/rails_best_practices/core/runner.rb— Executes AST-based code reviews by walking the syntax tree and delegating to check instanceslib/rails_best_practices/core/checks_loader.rb— Dynamically loads review checks from the reviews directory and third-party pluginslib/rails_best_practices/prepares.rb— Orchestrates preparation phase that extracts metadata (models, routes, controllers) before analysis
🛠️How to make changes
Add a New Code Review Check
- Create a new review class in lib/rails_best_practices/reviews/ that inherits from Review (
lib/rails_best_practices/reviews/your_new_review.rb) - Implement the prepare(source) method to declare what AST nodes you listen for (e.g., 'def' for method definitions) (
lib/rails_best_practices/reviews/your_new_review.rb) - Implement callback methods matching the node types (e.g., 'def_node(node)') to inspect and report issues (
lib/rails_best_practices/reviews/your_new_review.rb) - The check is automatically discovered and loaded by ChecksLoader during analyzer initialization (
lib/rails_best_practices/core/checks_loader.rb) - Write specs in spec/rails_best_practices/reviews/ to verify your check logic (
spec/rails_best_practices/reviews/your_new_review_spec.rb)
Add a New Rails Metadata Preparation Step
- Create a prepare class in lib/rails_best_practices/prepares/ that inherits from Prepare (
lib/rails_best_practices/prepares/your_new_prepare.rb) - Implement the prepare(source) method to declare which AST node types to process (
lib/rails_best_practices/prepares/your_new_prepare.rb) - Implement callback methods (e.g., 'class_node(node)') to extract metadata and store in the core data models (
lib/rails_best_practices/prepares/your_new_prepare.rb) - Register your prepare step in the Prepares orchestrator (
lib/rails_best_practices/prepares.rb)
Add Support for a New Template Engine or ORM
- Extend the parsing logic in core_ext or create a new template handler module (
lib/rails_best_practices/core_ext/your_template_engine.rb) - Update SchemaParser or ModelPrepare to recognize the new ORM syntax (
lib/rails_best_practices/prepares/schema_prepare.rb) - Create test fixtures and specs for the new format (
spec/fixtures/lib/rails_best_practices/)
🔧Why these technologies
- Ripper (Ruby stdlib AST parser) — Parses Ruby source code into AST without external dependencies; allows introspection of syntax trees
- Rack-based template engine support (ERB, Haml, Slim, Rabl) — Analyzes view templates to detect presentational logic that should move to controllers/models
- Gem reflection (RubyGems API) — Reads Gemfile to understand project dependencies and enforce conventions (e.g., turbo-sprockets)
- Ruby 1.9.3+ compatibility with symbol/method callbacks — Allows flexible check registration and node visitor pattern implementation without reflection overhead
⚖️Trade-offs already made
-
Pre-analysis metadata extraction phase before AST review execution
- Why: Reviews need context (model names, route definitions) to make accurate recommendations; single-pass would miss cross-file relationships
- Consequence: Two-pass analysis increases runtime; enables sophisticated checks like Law of Demeter and route customization validation
-
Dynamic check class loading via reflection rather than hardcoded registry
- Why: Allows third-party plugins to contribute custom reviews without patching core code
- Consequence: Slower startup time; enables extensibility at the cost of initialization overhead
-
Visitor pattern with node-type callbacks instead of single walk() method
- Why: Each check declares only the node types it cares about; reduces repeated tree traversals
- Consequence: Requires convention (e.g., 'def_node' callback for def statements); adds minor cognitive overhead for check authors
-
Inline disable comments (
# rails_best_practices:disable) instead of global suppressions- Why: Allows fine-grained control and documents specific exceptions in code
- Consequence: Developers must manually annotate code; more verbose but more explicit
🚫Non-goals (don't propose these)
- Not a linter for Ruby syntax errors—assumes valid, parseable code
- Not a security vulnerability scanner—focuses on architectural anti-patterns, not CVEs
- Not a formatter or code auto-fixer—reports issues only; does not modify source
- Not a real-time IDE plugin—command-line batch analysis tool
- Not ORM-agnostic—designed specifically for Rails patterns (ActiveRecord, Mongoid, MongoMapper)
🪤Traps & gotchas
- Checks auto-load from lib/rails_best_practices/checks/ but that directory is not shown in the file listing—contributors must understand the plugin discovery mechanism in checks_loader.rb. 2. The tool requires a valid Rails app structure (config/routes.rb, app/models/, etc.)—it will fail silently or produce incomplete results on non-Rails projects. 3. Inline disables use comment ripper (lib/rails_best_practices/inline_disables/) to parse Ruby comments; if comment syntax is atypical, disables will not work. 4. Template engine support (HAML, Slim, RABL) requires corresponding gems in the analyzed project's Gemfile; missing gems will skip those file types. 5. The core_ext/erubis.rb monkeypatches Erubis—version mismatches could break ERB parsing.
🏗️Architecture
💡Concepts to learn
- Abstract Syntax Tree (AST) Visitor Pattern — The entire check system uses visitor pattern to walk the AST generated by Ruby's Ripper; understanding this is essential to writing custom checks in lib/rails_best_practices/checks/
- Static Code Analysis — rails_best_practices never runs code; it infers issues by parsing source text and AST, so checks must work without runtime context—understanding this limitation is critical
- Rails Convention over Configuration — The tool encodes Rails idioms (e.g., models in app/models/, routes in config/routes.rb, naming patterns) and checks for violations; understanding Rails conventions is prerequisite to understanding the checks
- Template Engine Parsing — The tool supports ERB, HAML, Slim, and RABL via lib/rails_best_practices/core_ext/erubis.rb and template-specific loaders; knowing how templates are converted to AST is needed for view checks
- Domain-Driven Design (DDD) modeling — The core/ directory builds explicit domain models (Models, Controllers, Routes, ModelAssociations, Methods, etc.) that represent the Rails app in memory; this is a clean separation of concerns distinct from checks
- Plugin/Hook Architecture — Checks are auto-discovered plugins (via checks_loader.rb) that hook into visitor callbacks; adding a new rule requires only dropping a file in checks/ with no registration boilerplate
- Inline Code Disables via Comment Parsing — Users can suppress checks with special comments (lib/rails_best_practices/inline_disables/); the tool uses comment_ripper.rb to parse Ruby comments and extract disable directives without re-running Ripper
🔗Related repos
bbatsov/rubocop— Ruby linter and code style enforcer; overlaps with rails_best_practices on style checks but focuses on Ruby idioms rather than Rails patternspresidentbeef/brakeman— Security scanner for Rails apps; complements rails_best_practices by detecting vulnerabilities rather than code quality issuesruby-lint/ruby-lint— Alternative Ruby code analyzer using AST; similar static analysis approach but language-agnostic and less Rails-focusedreek/reek— Code smell detector for Ruby; overlaps on detecting bad patterns like long methods and god classes but not Rails-specificrails/rails— The Rails framework itself; rails_best_practices embeds knowledge of Rails conventions (routes, models, controllers, migrations) that are defined upstream
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive test suite for inline_disables module
The inline_disables directory (lib/rails_best_practices/inline_disables/) contains critical functionality for parsing and handling inline disable comments, but there's no visible corresponding test directory structure. This module deserves dedicated specs to ensure comment parsing works correctly across different scenarios (single-line comments, multi-line blocks, malformed comments, etc.). This will improve reliability of the core disable mechanism.
- [ ] Create spec/lib/rails_best_practices/inline_disables/ directory structure mirroring lib/rails_best_practices/inline_disables/
- [ ] Add spec/lib/rails_best_practices/inline_disables/comment_ripper_spec.rb with tests for various comment parsing scenarios
- [ ] Add spec/lib/rails_best_practices/inline_disables/inline_disable_spec.rb with tests for disable detection and rule filtering
- [ ] Run full test suite to ensure coverage meets project standards
Add integration tests for lexical checks (long lines, tabs, whitespace)
The lexicals directory contains three style checks (long_line_check, remove_tab_check, remove_trailing_whitespace_check) in lib/rails_best_practices/lexicals/. These are fundamental code quality checks that likely lack comprehensive integration tests. Adding tests will ensure they work correctly on real Ruby/Rails code samples with edge cases like comments, strings containing tabs, and mixed indentation.
- [ ] Create spec/lib/rails_best_practices/lexicals/ directory
- [ ] Add spec/lib/rails_best_practices/lexicals/long_line_check_spec.rb with fixtures for files with various line lengths
- [ ] Add spec/lib/rails_best_practices/lexicals/remove_tab_check_spec.rb testing tabs in code vs. strings vs. comments
- [ ] Add spec/lib/rails_best_practices/lexicals/remove_trailing_whitespace_check_spec.rb with edge cases
- [ ] Verify checks work correctly with the existing analyzer pipeline
Add missing tests for prepares modules (schema, initializer, route preparation)
The prepares directory (lib/rails_best_practices/prepares/) contains 8 prepare modules that parse Rails configuration files and populate the knowledge base. Several of these (schema_prepare, route_prepare, initializer_prepare, gemfile_prepare) are critical path components but likely lack thorough test coverage. This is high-value because bugs here silently degrade all downstream checks.
- [ ] Create spec/lib/rails_best_practices/prepares/ directory with test files for each prepare class
- [ ] Add spec/lib/rails_best_practices/prepares/schema_prepare_spec.rb with fixtures for different Rails schema.rb formats
- [ ] Add spec/lib/rails_best_practices/prepares/route_prepare_spec.rb testing Rails routes parsing (resources, nested routes, concerns)
- [ ] Add spec/lib/rails_best_practices/prepares/gemfile_prepare_spec.rb and initializer_prepare_spec.rb with realistic Gemfile and initializer samples
- [ ] Test that parsed data correctly populates core domain objects (Models, Controllers, Routes, etc.)
🌿Good first issues
- Add RSpec tests for lib/rails_best_practices/inline_disables/comment_ripper.rb to cover edge cases like nested comments and multi-line disable directives—currently no test file is visible in the file list.
- Document the Check class visitor interface with examples in lib/rails_best_practices/core/check.rb—add code examples showing how visit_method_add_arg, visit_class, etc. map to AST node types so new contributors can write checks without trial-and-error.
- Create a lib/rails_best_practices/checks/README.md that lists all existing checks with one-sentence descriptions and links to their source; this would make the tool's rule set discoverable without scanning source files.
⭐Top contributors
Click to expand
Top contributors
- @flyerhzm — 65 commits
- [@Awesome Code](https://github.com/Awesome Code) — 21 commits
- @mishina2228 — 4 commits
- @harsh-kaleris — 2 commits
- @mmotherwell — 2 commits
📝Recent commits
Click to expand
Recent commits
775a5d6— Bumping version to 1.23.4 (flyerhzm)0451159— 🐛 fix(deps): add ostruct dependency for Ruby 4.0 compatibility (flyerhzm)7a13645— use ruby 4.0.3 (flyerhzm)3051d41— support ruby 3.4 and 4.0 (flyerhzm)37405fd— drop ruby 2.7, 3.0, 3.1 (flyerhzm)4dcd762— Merge pull request #404 from harsh-kaleris/fix-haml-format-compilation (flyerhzm)eb85d0b— address copilot review comments (harsh-kaleris)e2f2aae— Fix Haml 6+ template compilation in Runner (Temple Engine#call) (harsh-kaleris)2ef4088— Bumping version to 1.23.3 (flyerhzm)9d0cdc7— update ruby to 3.4.7 (flyerhzm)
🔒Security observations
rails_best_practices is a static analysis tool for Rails projects with moderate security posture. Main concerns are around safe handling of untrusted code inputs, template injection prevention in ERB rendering, and CLI input validation to prevent path traversal. The tool's purpose (analyzing user-supplied Rails code) inherently carries risks if not properly sandboxed. Dependency security depends on proper maintenance of Gemfile.lock and regular vulnerability scanning. No critical vulnerabilities detected in the provided codebase structure, but careful attention is needed to input validation and AST parsing safety.
- Medium · Potential ERB Template Injection —
lib/rails_best_practices/core_ext/erubis.rb, assets/result.html.erb. The codebase includes ERB template processing (lib/rails_best_practices/core_ext/erubis.rb and assets/result.html.erb). If user-controlled input is rendered in templates without proper escaping, it could lead to template injection attacks. Fix: Ensure all ERB templates properly escape user input. Use <%= %> for output with automatic escaping and review any use of raw() or html_safe methods. - Medium · Dynamic Code Analysis Tool - Potential Unsafe AST Parsing —
lib/rails_best_practices/inline_disables/comment_ripper.rb, lib/rails_best_practices/core/runner.rb. The tool performs static analysis on Rails code including arbitrary Ruby files. The parsing of untrusted code through Ripper/AST libraries could potentially be exploited if input validation is insufficient. Fix: Validate and sanitize all file inputs before parsing. Consider running analysis in a sandboxed environment for untrusted codebases. Implement strict file type validation. - Medium · Missing Input Validation in CLI Processing —
lib/rails_best_practices/cli.rb, lib/rails_best_practices/option_parser.rb. The CLI tool (lib/rails_best_practices/cli.rb) accepts file paths and configuration as input. Insufficient path validation could lead to directory traversal attacks or unintended file access. Fix: Implement strict path validation to prevent directory traversal. Use File.expand_path and verify all paths are within expected directories. Validate all command-line arguments. - Low · Hardcoded Configuration Paths —
lib/rails_best_practices/core/configs.rb, lib/rails_best_practices/prepares/config_prepare.rb. The codebase references configuration files and paths throughout. Review to ensure no hardcoded sensitive paths, credentials, or API keys are embedded. Fix: Audit all configuration handling code. Ensure secrets are loaded from environment variables only, not hardcoded. Use a secrets management approach for sensitive data. - Low · No Visible Dependency Pinning Information —
Gemfile, Gemfile.lock. While a Gemfile exists, the provided context doesn't show Gemfile.lock content. Unpinned or outdated dependencies could introduce vulnerabilities. Fix: Ensure Gemfile.lock is committed and regularly updated. Run 'bundle audit' to check for known vulnerabilities in dependencies. Keep all gems updated. - Low · Potential Information Disclosure via Error Messages —
lib/rails_best_practices/core/error.rb, assets/result.html.erb. The tool generates error reports and results (assets/result.html.erb). Ensure error messages don't leak sensitive information about the analyzed codebase structure or system details. Fix: Review error output to ensure it doesn't expose sensitive information. Sanitize and limit error details in reports. Consider adding an output sanitization layer.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.