Configuration
Archspec.rb is Ruby.
Project
source "app/**/*.rb", "lib/**/*.rb"
ignore "tmp/**/*", "vendor/**/*"
todo "archspec_todo.yml"
Todo ids are computed from the rule, path, message, and evidence, not the line number, so entries survive edits that shift code.
Components
component :controllers, in: "app/controllers/**/*.rb"
component :models, in: "app/models/**/*.rb"
component :billing, namespace: "Billing"
component, layer, and role are aliases. Use the word that matches the architecture you are describing.
Declare one component per subdirectory with each_directory, which is handy for engines and packs:
each_directory "packs/*" do |name, path|
component name, in: "#{path}/**/*.rb"
end
Architectures
architecture :layered, layers: {
interface: "app/controllers/**/*.rb",
application: "app/services/**/*.rb",
domain: "app/models/**/*.rb"
}
Architectures define components and rules together. See Architectures.
Dependency Rules
controllers.can_use :models, :services
models.cannot_use :controllers
shared_kernel.can_only_be_used_by :billing, :catalog
can_use is an allowlist for what a component may depend on. cannot_use forbids specific components. can_only_be_used_by is the inverse of can_use: it limits who may depend on the component. See Dependency Rules.
Method Rules
services.must_implement :call
services.must_implement_one_of :call, :resolve
services.cannot_call :render, :redirect_to, :params, :session
These are name-based checks. They are useful for Rails boundaries and method protocols. See Method Rules and Protocol Rules.
For projects that avoid anonymous command-object style APIs, forbid method definitions too:
library.cannot_define :call
library.cannot_instantiate_and_invoke
See Object Rules.
Constant Rules
models.cannot_reference_constants "ActionController", "ActionView"
Use this when the dependency is better expressed as a framework constant than a component.
See Constant Rules.
Cycles
no_cycles!
no_cycles! checks component dependency cycles.
See Cycle Rules.
Suppressions
# archspec:disable-next-line dependencies.forbid -- legacy export
Admin::UsersController
Supported forms:
archspec:disable-next-line RULE -- reason
archspec:disable-line RULE -- reason
archspec:disable RULE -- reason
archspec:enable RULE
Omit RULE to suppress all ArchSpec rules on that line or block.