In part 3 we finished off our budget functionality, but currently there is no way to exclude certain categories from the budget. Today we’ll close off the budget enhancement by adding the ability to scope which categories are included in the budget.
Today’s objective
Our budget feature is complete but as mentionned last time out, we would like to have more control over what categories appear in our budget, i.e. we’d like to be able to exclude certain categories:
The approach we’ll take with this is to add a new field to the categories
table, that indicates whether or not a particular category should be included in the budget.
Getting started
As previously mentionned I’m not sure this is really a “follow along” type of series, but it is possible to follow along if you wish.
If you’ve been following along you can continue with the code from part 3, or you can grab the code from GitHub.
Clone the Repo:
If cloning:
Terminal
After grabbing the code we should set our local Ruby version and run bundle install
.
Terminal
Terminal
Next let’s create a new branch for today’s work.
Terminal
With that out of the way, let’s get to it!
Where we’re starting from
Let’s fire up the server and have a quick look at our current category page.
Terminal
So basically we need a new column that allows the user to include / exclude a category from displaying in the budget page.
Updating the Category page
The first step will be to create a migration for a new database column. We’ll create an include_in_budget
column on categories
.
Terminal
Let’s update the migration to set the default value of the column to true
. We’ll assume that the majority of categories will be included on the budget page so defaulting to true
seems reasonable for existing categories and any new categories the user creates in the future.
/db/migrate/datestamp
_add_include_in_budget_to_categories.rb
Now let’s run the migration.
Terminal
We now need to make a small change to the Category
model so that we can access the include_in_budget
field. We do so by including it in the attr_accessible
items.
/app/models/category.rb
Next we need to update the category view to include the new field:
/app/views/categories/_category.html.erb
We’ve added a checkbox column which can be used to toggle whether the category should be included on the budget page. We’ve set remote: true
in order to make this an Ajax
style checkbox. We need to add the new controller method and also a new route for the toggle_budget_inclusion_flag
action.
Before updating the controller and routes let’s update the main category
view to include a table header.
/app/views/categories/index.html.erb …line 13
Now for the route.
/config/routes.rb …line 15
And finally the update to the controller.
/app/controllers/categories_controller.rb …line 26
Nothing complicated… the method just grabs the category associated with the passed in id
and toggles the include_in_budget
value.
The above works but doesn’t looks so good, the table is a little squished!
Let’s update the category styling. For some reason we had the width of the table set to 10px
. We can just remove that from our style.
/assets/stylesheets/categories.css.scss
That looks better!
The final step is to update the budget
controller to only load categories the user has specified they want in their budget.
/app/controllers/budget_controller.rb …line 10
And with that we can now exclude purely income categories such as Pay
from our budget:
Updating the budget status widget
The other issue we discussed in part 3 was that the budget status doesn’t update without a page refresh. This is pretty easy to fix, we just need make a few updates to budget.js
.
/assets/javascripts/budget.js …line 9
All we’ve done is add a new function updateBudgetStatus
that sets the budget status text and style based on whether the plus-minus-total
we already calculate on the page is positive or negative. We add a call to this new function where we bind to the ajax:success
event so that the status is updated anytime a change is made to a budget item.
The status now updates without requiring a page refresh!
Tests
Before finishing up for the day let’s update a few tests. We should update the category
model test and the budget
page test.
Let’s start with the category_spec
.
/spec/models/category_spec.rb …line 24
We’ve just added a check for the new field.
And now we’ll want to update the budget_spec
to ensure it tests for categories that should not be loaded.
/spec/requests/budget_spec.rb …line 32
All we’ve done is created a new category which we expect not to appear on the page (since include_in_budget
is false). The rest of the test can stay as is.
Let’s make sure everything is still passing. Remember since we’ve updated our database we need to apply the migration to our test database before running the tests.
Terminal
Terminal
Fantastic, done and dusted! We can merge our code from today into our budget feature branch.
Terminal
Now we can merge the budget-feature-branch to master and deploy our enhancement! These steps are similar to what we did in the final post of the original series of posts around our budget app so I won’t go over them here.
The only deviation from the steps above is that since we’ve added new javascript and css files we need to precompile the assets prior to deploying to heroku, i.e. something along the lines of:
Terminal
Summary
That’s it for the new budget feature and the end of this series of posts. Thanks for reading and hope you enjoyed!