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::Reportlives inlib/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 loadlib/and run it; tests mirror thelib/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.