Skip to content

Commit be1b60a

Browse files
committed
Add Chartkick donut chart to budgets index and update tests
1 parent 9bfdb4e commit be1b60a

14 files changed

Lines changed: 97 additions & 42 deletions

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,5 @@ gem "view_component", "~> 3.21"
8888
gem "requestjs-rails", "~> 0.0.13"
8989

9090
gem "pagy", "~> 9.3"
91+
92+
gem "chartkick"

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ GEM
102102
rack-test (>= 0.6.3)
103103
regexp_parser (>= 1.5, < 3.0)
104104
xpath (~> 3.2)
105+
chartkick (5.2.0)
105106
concurrent-ruby (1.3.5)
106107
connection_pool (2.5.3)
107108
crass (1.0.6)
@@ -436,6 +437,7 @@ DEPENDENCIES
436437
bootsnap
437438
brakeman
438439
capybara
440+
chartkick
439441
debug
440442
erb-formatter
441443
erb_lint

app/controllers/budgets_controller.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ class BudgetsController < ApplicationController
66
# GET /budgets or /budgets.json
77
def index
88
@budgets = Budget.includes(category: [:transactions]).all
9+
10+
transaction_sums = Transaction.group(:category_id).sum(:amount)
11+
category_ids = transaction_sums.keys.compact
12+
categories = Category.where(id: category_ids).pluck(:id, :name).to_h
13+
14+
@donut_data = transaction_sums.each_with_object({}) do |(category_id, amount), hash|
15+
label = categories[category_id] || "Unknown"
16+
hash[label] = amount.abs
17+
end
918
end
1019

1120
# GET /budgets/1 or /budgets/1.json

app/javascript/application.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
2-
import "@hotwired/turbo-rails"
3-
import "controllers"
4-
import "@rails/request.js"
2+
import "@hotwired/turbo-rails";
3+
import "controllers";
4+
import "@rails/request.js";
5+
import "chartkick";
6+
import "Chart.bundle";

app/views/budgets/index.html.erb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@
2020
id="notice"
2121
><%= notice %></p>
2222
<% end %>
23-
23+
2424
<article class="bg-white rounded-lg px-5 py-7 space-y-5">
25-
25+
<%= pie_chart @donut_data,
26+
donut: true,
27+
legend: false,
28+
prefix: "$",
29+
library: {
30+
cutout: "70%",
31+
} %>
2632
</article>
2733

2834
<div>

app/views/categories/show.html.erb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<p>
2+
<strong>Name:</strong>
3+
<%= @category.name %>
4+
</p>
5+
6+
<%= link_to "Edit", edit_category_path(@category) %>
7+
|
8+
<%= link_to "Back", categories_path %>

config/importmap.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
pin "@hotwired/stimulus", to: "stimulus.min.js"
88
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
99
pin_all_from "app/javascript/controllers", under: "controllers"
10+
pin "chartkick", to: "chartkick.js"
11+
pin "Chart.bundle", to: "Chart.bundle.js"

test/controllers/bills_controller_test.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
require "test_helper"
44

55
class BillsControllerTest < ActionDispatch::IntegrationTest
6+
setup do
7+
sign_in_as users(:one)
8+
end
9+
610
test "should get index" do
7-
get bills_index_url
11+
get bills_url
812
assert_response :success
913
end
1014
end

test/controllers/budgets_controller_test.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
class BudgetsControllerTest < ActionDispatch::IntegrationTest
66
setup do
77
@budget = budgets(:one)
8+
sign_in_as users(:one)
89
end
910

1011
test "should get index" do
@@ -20,10 +21,10 @@ class BudgetsControllerTest < ActionDispatch::IntegrationTest
2021
test "should create budget" do
2122
assert_difference("Budget.count") do
2223
post budgets_url,
23-
params: {budget: {category: @budget.category, maximum: @budget.maximum, theme: @budget.theme}}
24+
params: {budget: {category_id: @budget.category_id, maximum: @budget.maximum, theme: @budget.theme}}
2425
end
2526

26-
assert_redirected_to budget_url(Budget.last)
27+
assert_redirected_to budgets_path
2728
end
2829

2930
test "should show budget" do
@@ -38,15 +39,15 @@ class BudgetsControllerTest < ActionDispatch::IntegrationTest
3839

3940
test "should update budget" do
4041
patch budget_url(@budget),
41-
params: {budget: {category: @budget.category, maximum: @budget.maximum, theme: @budget.theme}}
42-
assert_redirected_to budget_url(@budget)
42+
params: {budget: {category_id: @budget.category_id, maximum: @budget.maximum, theme: @budget.theme}}
43+
assert_redirected_to budgets_path
4344
end
4445

4546
test "should destroy budget" do
4647
assert_difference("Budget.count", -1) do
4748
delete budget_url(@budget)
4849
end
4950

50-
assert_redirected_to budgets_url
51+
assert_redirected_to budgets_path
5152
end
5253
end
Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,53 @@
1+
# frozen_string_literal: true
2+
13
require "test_helper"
24

35
class CategoriesControllerTest < ActionDispatch::IntegrationTest
6+
setup do
7+
@category = categories(:one)
8+
sign_in_as users(:one)
9+
end
10+
411
test "should get index" do
5-
get categories_index_url
12+
get categories_url
613
assert_response :success
714
end
815

916
test "should get new" do
10-
get categories_new_url
17+
get new_category_url
1118
assert_response :success
1219
end
1320

14-
test "should get create" do
15-
get categories_create_url
21+
test "should create category" do
22+
assert_difference("Category.count") do
23+
post categories_url, params: {category: {name: "New Category"}}
24+
end
25+
26+
assert_redirected_to categories_url
27+
end
28+
29+
test "should show category" do
30+
get category_url(@category)
1631
assert_response :success
1732
end
1833

1934
test "should get edit" do
20-
get categories_edit_url
35+
get edit_category_url(@category)
2136
assert_response :success
2237
end
2338

24-
test "should get update" do
25-
get categories_update_url
26-
assert_response :success
39+
test "should update category" do
40+
patch category_url(@category), params: {category: {name: "Updated Category"}}
41+
assert_redirected_to categories_url
2742
end
2843

29-
test "should get destroy" do
30-
get categories_destroy_url
31-
assert_response :success
44+
test "should destroy category" do
45+
# Create a category that is not associated with any budget or transaction
46+
category_to_destroy = Category.create!(name: "To be destroyed")
47+
assert_difference("Category.count", -1) do
48+
delete category_url(category_to_destroy)
49+
end
50+
51+
assert_redirected_to categories_url
3252
end
3353
end

0 commit comments

Comments
 (0)