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.
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.
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:
After grabbing the code we should set our local Ruby version and run
Next let’s create a new branch for today’s work.
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.
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
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.
Now let’s run the migration.
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
Next we need to update the category view to include the new field:
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
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
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.
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
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!
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
/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.
Fantastic, done and dusted! We can merge our code from today into our budget feature branch.
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.
That’s it for the new budget feature and the end of this series of posts. Thanks for reading and hope you enjoyed!