A thoughtbot-style Rails application for managing company expenses
Ruby CSS JavaScript Other
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
app
bin
config
db
lib
public
spec
.coveralls.yml
.gitignore
.rspec
.ruby-version
.sample.env
.travis.yml
Gemfile
Gemfile.lock
LICENSE.txt
Procfile
README.md
Rakefile
config.ru

README.md

Expense manager

Build Status Code Climate Coverage Status

This is a Ruby-on-Rails application for tracking company expenses. Here are some interesting aspects:

The facade pattern

The dashboard shows users several pieces of loosely related data together. Instead of reaching across many different models from the controller or view, I created a new object to serve as a single interface (or "Facade") to all the data that is displayed in the view. This makes it possible to access data from a complex API while keeping the controller simple and the logic easy to test.

Scalable spreadsheet-like searching and sorting

Users can search and sort large amounts of data with online "spreadsheets". app/models/user_expense_search and app/models/datatable are responsible for returning JSON compatible with the DataTables.js API, while using Sunspot for searching and ordering.

Sunspot auto-indexes expenses after they are saved or deleted. In addition, I added a mixin module to the related User, Department, and JobTitle classes. Whenever a record changes, the module creates a simple background job to reindex their associated expenses.

Date-based SQL joins

Rails is great at joining records by integer foreign keys. But sometimes, other kinds of joins are necessary for a DRY, normalized database design.

When displaying sums of expenses converted into a single currency, the Expense model joins expenses to exchange rates through a combination of currencies and date ranges, rather than through an integer id. See self.sum_in(currency) and self.joins_exchange_rates(currency).

To ensure each expense is joined to exactly one exchange rate, I used Postgres check constraints with daterange data types and the "&&" overlap operator to prevent records with overlapping currencies and date ranges from being created. Since financial data is at stake, I wrote this validation in the database rather than in ActiveRecord, so that it cannot be easily bypassed.

Getting started

expense_manager comes equipped with a self-setup script:

% ./bin/setup

After setting up, you can run the application using foreman:

% foreman start

Guidelines

Use the following guides for getting things done, programming well, and programming in style.

License

The MIT License. See LICENSE.txt