Skip to content
AgileLogics
5 min read

Code Organization and RuboCop

Prerequisites: Gems and Bundler, Testing with Minitest

Once a project has more than a handful of files, a consistent layout matters. Ruby projects follow a widely-shared convention.

A typical project layout

expense_tracker/
├── Gemfile
├── Gemfile.lock
├── .rubocop.yml
├── bin/
│   └── expense_tracker      # the executable entry point
├── lib/
│   ├── expense_tracker.rb   # requires everything below
│   └── expense_tracker/
│       ├── expense.rb       # ExpenseTracker::Expense
│       └── report.rb        # ExpenseTracker::Report
└── test/                    # or spec/ for RSpec
    └── expense_test.rb

Conventions:

  • One class or module per file, and the file name is the snake_case version of the class name: ExpenseTracker::Report lives in lib/expense_tracker/report.rb.
  • Everything is namespaced inside one top-level module named after the project.
  • lib/ holds the code; bin/ holds small scripts that load lib/ and run it; tests mirror the lib/ structure.
# lib/expense_tracker.rb
require_relative "expense_tracker/expense"
require_relative "expense_tracker/report"

module ExpenseTracker
end

Larger projects (and Rails) use the Zeitwerk gem to load files automatically from their names, so no manual requires are needed.

RuboCop

RuboCop checks your code against the community Ruby Style Guide and catches likely bugs:

bundle add rubocop --group development
bundle exec rubocop
lib/expense_tracker/report.rb:4:5: C: Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
    puts 'Report'
         ^^^^^^^^

1 file inspected, 1 offense detected, 1 offense autocorrectable

bundle exec rubocop -a fixes the safely-correctable offenses for you. Rules can be tuned in .rubocop.yml. Standard (the standard gem) is a popular alternative: a RuboCop configuration with no settings to argue about.

Run the linter in your editor (Ruby LSP does this) and in CI, so style never has to be discussed in code review.

Common mistakes

  • One huge file with every class in it. Split by responsibility early.
  • Disabling every RuboCop rule that complains. Read the explanation first — many rules point to real bugs.