Ruby & Rails Naming Conventions
Names communicate design intent. Align with Ruby community norms so every class, module, and database column makes sense immediately. Consistency also unlocks Rails’ magic—pluralization, autoloading, and helpers rely on conventional names.
Canonical Patterns
snake_case
Methods, variables, file names (`calculate_total`, `application_controller.rb`). Reserve leading underscores for intentionally unused params.
CamelCase
Classes and modules (`LearningPath`, `Ai::ResponseService`). Match file paths: `app/services/ai/response_service.rb`.
SCREAMING_SNAKE_CASE
Constants and frozen configuration (`DEFAULT_TIMEOUT`, `ALLOWED_FORMATS`). Freeze collections to prevent accidental mutation.
Files, Folders, and Autoloading
- Match file paths to namespaces. If the class is `RubyTopics::GuidedTour`, locate it at `app/` with the same nested directories.
- Use pluralized directory names for collections (`controllers`, `services`, `jobs`), singular for domain boundaries (`lib/tasks`).
- Component previews and ViewComponents keep the `*_component.rb` suffix to aid auto-loading and search.
Database Artifacts
Tables & Columns
- Tables are plural (`users`, `learning_paths`). Join tables use alphabetical names (`courses_topics`).
- Foreign keys end with `_id` and reference singular models (`user_id`).
- Boolean columns read like questions (`published`, `archived`).
Migrations
Use descriptive verbs (`create_learning_paths`, `add_index_to_messages_on_chat_id`). Keep filenames aligned with the generated class names to prevent double takes in migrations history.
Tests, Fixtures, and Factories
- Test files mirror the source path: `app/services/ruby/style_enforcer.rb` ➝ `test/services/ruby/style_enforcer_test.rb`.
- Factory names stay singular (`factory :user do ... end`) while sequences use descriptive names (`sequence(:slug) { |n| "topic-\#{n}" }`).
- System tests describe intent (`test 'user completes ruby lesson flow' do ... end`).
Quick Reference Table
Artifact
`UserProfileComponent`
`app/components/user_profile_component.rb`
Method
`def mark_complete!`
Predicate? Use `complete?`
Database
Table: `learning_paths`
FK: `learning_path_id`
Spec / Test
`test/services/` mirror source
Describe scenario + expectation