For my Ruby on Rails project I had decided to build a Money Manager app since it would lend itself well to scope methods (such as total expenses by category or all expenses from today or this month). I started the project by sketching out my models and their relations ships on a piece of paper (Users have many Expenses and many Categories through expenses, Expenses belong to Category and User). I found that diagrams are way easier to wrap my head around than just writing down the relationships themselves. Then I wrote out some notes on some of the things the application would need to do in order to meet the project requirements (such as validations, scope methods, error display, nested resources, etc).
Once I had a plan I used “rails generate model” to create my model files and migration files and then started testing out my models. Since expenses include a currency value, I needed to set a field in my Expenses table to some numeric data type. I had started with decimal but when I tested my seed data, none of my expenses saved to the database so I had to investigate. For some reason, if you use a decimal or numeric data type in your table in Rails the model tries to save the value as a BigDecimal class object…which can’t be saved in the database and so the call to save the Expense record to the database was failing. I didn’t want to use a text field since I knew I wanted to be able to run sums and other arithmetic on the field so I played with different field types until I found one that would behave. Float seemed to work without giving me any grief. Bonus! During my Google searching I found a handy ActionView helper called number_to_currency that I could use to make my frumpy numbers look nice in the views. I thought that a nice find and worth the trouble caused by the numerical data types.
After I had my models up and working in general I decided to stay in the models and work on some scope methods that I might use in my application later on in the process. The class scope methods lab that was part of the course work was one of the hardest labs I’ve had to work on so I wanted to get the scope methods worked out early on in the project while I was fresh and excited (ie. before I got tired and cranky). I drew up quite a few methods and ended up not using them all but I kept them since I think that I can use them later when I flesh out the statistics part of application as one of my stretch goals.
With my models and scope methods all worked out I moved on to controllers and views. I didn’t use the rails generate controllers helper since it creates a ton of stuff that I wasn’t sure I’d need so I just created the files and folders that I wanted manually. My Users and Sessions Controllers were pretty straight forward but the Expenses Controller was a bit of a challenge because all the routes/actions were nested and I needed to validate both the user and the expense (in the case of an existing expense). I built quite a few helper methods to ensure that my actions were “skinny”. I also struggled a bit with trying to figure out the best way to “recycle” my table code. I had started by creating a partial view for the table header and then adding the rows to my specific view files. But then I had to check several places to figure out if my rows and headers had the same data in the same order. In the end I made two helper methods that create the header and the data rows for me and if I need to adjust them they are both in the same place so it is easy to change them together.
Lastly I hooked my app up to OmniAuth so users can login with Facebook. I wanted to use Instagram or Google, and I may do that in the future, but I had reached “tired and cranky” so I did what I knew would work instead of fighting with a different gem/configuration. Hooking my app up to other OmniAuth strategies will also be a goal for the future.
All in all, I’m pretty pleased with my app. Future goals include adding other OmniAuth strategies (as already mentioned), fleshing out my statistics page, making the CSS a little nicer and adding a second join model for budgets (between users and categories) so users can keep their expenses within the limits of their budgets by category. I think this last part will require aliases within the relationships which will be a nice challenge.