This is a Ruby on Rails application that helps users with benefits applications. The application uses:
- Ruby on Rails 8
- PostgreSQL database
- Bootstrap 5.3 for UI styling
- Hotwire (Turbo and Stimulus) for frontend interactivity
- RSpec for testing
The project follows standard Rails conventions:
app/
- Contains the core application code (MVC)bin/
- Contains executable scriptsconfig/
- Contains configuration filesdb/
- Contains database schema and migrationslib/
- Contains library codepublic/
- Contains public assetsspec/
- Contains testsscripts/
- Contains utility scripts
- Use
bin/rails server
to start the development server - Use
bin/rails console
to start the Rails console
- Use
bin/rails db:migrate
to run pending migrations - Use
bin/rails db:seed
to seed the database - Use
bin/rails db:reset
to reset the database
- Use
bin/rspec
to run all tests - Use
bin/rspec [path]
for specific tests
- Write concise, idiomatic Ruby code with accurate examples
- Follow Rails conventions and best practices
- Use object-oriented and functional programming patterns as appropriate
- Prefer iteration and modularization over code duplication
- Use descriptive variable and method names (e.g., user_signed_in?, calculate_total)
- Structure files according to Rails conventions (MVC, concerns, helpers, etc.)
- If a form url or controller redirect is to an action in the same controller, use a hash with the action name as the key e.g.
{ action: :new }
- When making migrations, use
text
for all string fields; never usestring
orvarchar
- Use snake_case for file names, method names, and variables
- Use CamelCase for class and module names
- Follow Rails naming conventions for models, controllers, and views
- Use Ruby 3.x features when appropriate (e.g., pattern matching, endless methods)
- Leverage Rails' built-in helpers and methods
- Use ActiveRecord effectively for database operations
- Follow the Ruby Style Guide (https://rubystyle.guide/)
- Use Ruby's expressive syntax (e.g., unless, ||=, &.)
- Prefer double quotes for strings
- Always strip whitespace at the end of lines and ensure a blank line exists at the end of the file
- When adding new controllers or actions, don't forget to update the routes.rb
- Use
expect
syntax instead ofrequire
/allow
for strong parameters:# Good params.expect(user: [:name, :favorite_pie]) # Bad params.require(:user).permit(:name, :favorite_pie)
- Unless parameters are reused more than once, assign strong parameters to a local variable rather than a method
- When linking or redirecting to an action in the same controller, use
url_for(action: "the_action")
instead of path helpers
- Use the custom form builder
FrontdoorForm
which contains helpers for structure bootstrap forms. - When using
FrontdoorForm
, do not add Bootstrap classes likeform-label
/form-control
/form-select
; they're already added by the FrontdoorForm builder. - Most simple form inputs will have this structure of
group
,label
,input
, anderrors
:<%= f.group(:first_name, class: "col-3") do %> <%= f.label :first_name, "First Name" %> <%= f.input :first_name %> <%= f.errors :first_name %> <% end %>
- When creating
select
tags, useinclude_blank: "string"
instead of manually adding a blank option to the list of options.
- Always create a migration using
bin/rails g migration <NAME>
. If a migration has been created in the current development feature branch, rollback the migration, edit it and then roll forward rather than creating a new migration. - Use
text
for all string fields; never usestring
orvarchar
- Use
datetime
instead oftimestamp
- Assume that Boolean values should be nullable unless specified
- Write tests using RSpec. It's ok to put multiple assertions in the same example
- Use factories (FactoryBot) for test data generation
- Prefer real objects over mocks unless there is an external dependency like a third party API call. Use
instance_double
if necessary; neverdouble
- Don't test declarative configuration. For validations, only test that it's not valid when the validation is violated.
shoulda-matchers
is not used. - Test controllers behaviorally: assert on status code and/or data changes
- Use Timecop for time traveling
- When writing System Tests, use
css_id(*)
andcss_class(*)
instead of"#{dom_id(*)}"
"#{dom_class(*)}"
- Use Capybara async matchers and expectations and generally avoid asserting on
find
methods that may be flaky.
- Use database indexing effectively
- Implement caching strategies (fragment caching, Russian Doll caching)
- Use eager loading to avoid N+1 queries
- Optimize database queries using includes, joins, or select