Class: Railsmith::ArchChecks::MissingServiceUsageChecker

Inherits:
Object
  • Object
show all
Defined in:
lib/railsmith/arch_checks/missing_service_usage_checker.rb

Overview

Scans public controller action methods for model access without service or operation delegation.

Flags methods that call ActiveRecord methods directly but contain no reference to a *Service / *Operation entrypoint (.new / .call), a namespaced domain operation (Domain::...::Name.call / .new, including legacy ::Operations::... paths), indicating the data-layer interaction has not been routed through the layer.

Method boundaries use standard 2-space Ruby indentation (RuboCop default). Methods after a bare private / protected keyword are skipped. Single-line and endless method definitions are out of scope for this checker.

Usage:

checker = Railsmith::ArchChecks::MissingServiceUsageChecker.new
violations = checker.check(path: "app/controllers")

Constant Summary collapse

SERVICE_OR_OPERATION_RE =

*Service / *Operation entrypoints (namespaced tail allowed).

/
  \b
  (?:[A-Z][A-Za-z0-9]*::)*
  [A-Z][A-Za-z0-9]*(?:Service|Operation)
  (?:::[A-Z][A-Za-z0-9]*)*
  \.(?:new|call)
  \b
/x
DOMAIN_OPERATION_RE =

Domain operations from the generator: legacy ...::Operations::…+ (e.g. Billing::Operations::Invoices::Create.call).

/
  \b
  (?:[A-Z][A-Za-z0-9]*::)+
  Operations::
  (?:[A-Z][A-Za-z0-9]*::)*
  [A-Z][A-Za-z0-9]*
  \.(?:new|call)
  \b
/x
FLAT_DOMAIN_OPERATION_RE =

1.1.0+ layout: Domain::Module::Operation.call with no Operations segment (three+ constants).

/
  \b
  (?:[A-Z][A-Za-z0-9]*::){2,}
  [A-Z][A-Za-z0-9]*
  \.(?:new|call)
  \b
/x

Instance Method Summary collapse

Instance Method Details

#check(path:) ⇒ Array<Violation>

Parameters:

  • path (String)

    directory to scan (recursively for *_controller.rb files)

Returns:



167
168
169
170
# File 'lib/railsmith/arch_checks/missing_service_usage_checker.rb', line 167

def check(path:)
  Dir.glob(File.join(path, "**", "*_controller.rb"))
     .flat_map { |file| check_file(file) }
end

#check_file(file) ⇒ Array<Violation>

Parameters:

  • file (String)

    path to a single Ruby source file

Returns:



174
175
176
177
# File 'lib/railsmith/arch_checks/missing_service_usage_checker.rb', line 174

def check_file(file)
  lines = File.readlines(file, chomp: true)
  extract_action_methods(lines).filter_map { |method| method_violation(file, method) }
end