Detector::Ruby::Rails
Constants
Rails APIs that cannot appear in a project that is not Rails, so a
single .rb or .ru file is enough to place the whole tree.
The dependency declaration is the better marker when it is there, but
it is only there when the scan reaches the manifest. Point noir at a
Rails app's config/ directory, at an engine whose gemspec does not
name the framework, or at a service inside a monorepo scanned
app-by-app, and there is no Gemfile in the walk — the app detects as
nothing, the Rails analyzer never runs, and every route the app
declares is lost. That is the same gap the Django detector closes for
DRF-only apps, and it is worth closing here because the file the
analyzer actually reads, config/routes.rb, is itself proof:
.routes.draw is the Rails routing DSL and belongs to no other
framework.
Modern Rails apps frequently skip the umbrella rails dependency and
pull the individual frameworks they actually use (railties +
actionpack + activerecord + ...). Treat railties as a unique marker
— it has no standalone use outside Rails — so those apps are still
detected. Multi-engine projects (Spree, Solidus) push their Gemfile to
gemspec and declare the dependency inside <gem>.gemspec instead;
the tolerant matchers accept the s.add_dependency('rails', ...)
parenthesized call form those gemspecs commonly use.
Class methods
The tech name without needing an instance, so the registry can be read off the classes themselves rather than from a parallel list.
Instance methods
Cheap filename-only filter the detector pass uses to skip
detect on files the detector cannot possibly match. The
default true preserves prior behavior (every detector runs on
every file). Override with the same predicate the body of
detect starts with — e.g., filename.ends_with?(".py") for a
Python framework detector — so the detector loop avoids the
detect dispatch on files outside the detector's language.
On large codebases (saleor's 4255 .py files) this lifts ~100
virtual detect calls per file out of the hot loop because
most detectors' inner first-line is exactly this kind of cheap
filename check.