プログラミング初心者が家計簿アプリを作ってみた時の話

以前、プログラミング学習４ヶ月目ぐらいにアプリを開発してみたことがあったので、その時のことを思い出しながら書いていきます。当時は（今でも）プログラミング初心者で、完成度は全然高くないけど、プログラミングの勉強を始めたばかりの方に、一部でも役に立てればと思い書こうと思いました。

目次：
１、プロフィール
２、アプリ概要
３、取り組んだ理由
４、所感
５、取り組みの流れ
６、アプリ実装内容について
７、学んだ事・大変だったこと
８、改善点
９、まとめ

#１、プロフィール
2019年2月に前職を退職し、プログラミングスクールで3ヶ月学んだ後、就職活動を経て夏よりエンジニアとして就職しました。

#２、アプリ概要
オリジナルの家計簿アプリ
開発環境：Ruby on Rails, MySQL, Github
開発期間：スクール卒業後２〜３週間程度

#3、取り組んだ理由
・スクール卒業後、より理解を深めたいと思い（スクールではついていくのがやっとだったので...)
・就職活動において話の種になるかなと思った（これは経験者からアドバイス。実際面接で盛り上がったことも！）

#４、所感
まず一言、プログラミングを勉強して少し経って慣れてきた人は、一回自分でアプリを作ってみるのはマジでオススメ。

スクール在籍時はカリキュラムにしろ、チーム開発にしろ課題が与えられて、「見本」もあった。よく分かんないけど進んでいったというのが正直な気持ちだった。理解があやふやなことも多いけど大丈夫かな？という感じ。

個人でオリジナルアプリを開発するということは、設計や実装機能も自分が考えなければならないし、カリキュラムもない。つまり少ない知識を総動員し、頭をフル回転させる必要があり、プログラミングの勉強としては最強のアウトプットになる。

そして何より楽しい。

完成度やレベルの高い機能の実装は別として、とりあえず自分で作ってみるというのはかなり力になる。

#5、取り組みの流れ
###何のアプリを作るか考える
スクールではSNS系の開発をしていたので、他の分野をやってみたい、またプログラミングの流れやデータベースを理解するには、家計簿あたりがちょうどいいんじゃないかなと思い家計簿を作ることにしました。自分自身も家計簿アプリを使ったことはあったのでイメージはありました。

###全体を設計
家計簿に最低限必要な機能は何か、学習のために実装してみたい機能は何か等を考え、各ページの設計を行う。
構成を考えてみてとにかく紙に書き出す。

###DB設計
どのサービスもそうですが、家計簿もデータの扱いは非常に重要。データがうまく取り出せないとなると家計簿の程をなさなくなってしまう。必要なテーブル、関係性など、こちらも紙に書き出し整理。

###実装へ
####１、登録・ログインページを実装

####２、各ページを作る（とりあえず簡易的なもの）

コントローラやビュー、ルーティングなどを一通り設定し、骨組みを作り全体を見渡せるようにして、これから実装していくイメージを掴む

####３、各機能の実装

動かしながら試行錯誤。バリデーションも意識しながら実装。ページのデザインもちょっとずつ肉付け。

####４、リファクタリングなど細かな部分

以上、自分が実際に取り組んだ流れを紹介しましたが、経験豊かなプログラマの方がやればもっと効率的にできるのだと思います。。。
多少の参考になればと思います。

#６、アプリ実装内容について
主な機能：

・新規登録、ログインができる

・収入・支出を日別、カテゴリー別に入力し保存できる

・月毎に予算を設定できる

・トップページには、当月の収入予算と支出予算、及びその日時点での収入と支出額が自動で表示されその差額が分かる

・年と月を選択するとカテゴリー毎の金額と全体における割合、そして月の合計額が分かる。

など

見た目をちょっとだけ紹介
最後に記載した、カテゴリー毎の収支詳細ページを紹介（たいしてデザインは凝っていない笑）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496614/64b0da90-4f27-26c1-8084-8333c2133c6c.png)



#７、学んだこと・大変だったこと
###学んだこと
・自分でどのようなアプリを作るかというところから構想する。

・アプリに必要な機能、処理の流れ、設計など一連を自分で考える。

・カリキュラムにない部分を自分で調べるため、調べる力がつく。

・考えても、調べても試行錯誤しても分からない時は、某有名サイトで質問してみる。

その際、全く知らない、アプリの背景も分からない方々に質問するので、どのようにしたら質問の意図が分かりやすく伝わるか一旦自分自身でまとめる。

など

**高機能で完成度高いものよりまずは、自分で色々試行錯誤しながら動かしてみる。分からないところは、調べ、悩み、成功する毎にそれがいい経験とると実感。**
**「自分の頭で考える」というのが一番身になったかなと。**


コードもちょっと紹介

トップページで当月の収入予算と支出予算を表示：

```
def index

　@name = current_user.name

　# 今月は何月か

　time = Time.now
　this_month = time.month
　this_year = time.year

　# 設定した予算の今月

　@income_budget = Budget.find_by(year: this_year, month: this_month).income_amount
　@spending_budget = Budget.find_by(year: this_year, month: this_month).spending_amount
```

今月のその時点での収入額、支出額を表示：

```
# 今月の現在の収支状況

@current_income = Income.group("YEAR(date)").group("MONTH(date)").sum(:amount)
@current_income[[this_year,this_month]]
@current_income_view = @current_income[[this_year,this_month]]

@current_spending = Spending.group("YEAR(date)").group("MONTH(date)").sum(:amount)
@current_spending[[this_year,this_month]]¥
@current_spending_view = @current_spending[[this_year,this_month]]

```


###大変だったこと
・勉強になった点の裏返しですが、設計が難しい。
自分は完璧主義なところがあり、設計は妥協できないと考えていましたが、おそらく今の自分の力では完璧な設計は難しいと考え、とりあえず見切り発車しました。案の定後から変更点や抜け漏れがたくさん出てきました。

・家計簿アプリはSNSアプリなどと違い「分析」をすることが機能の主な役割なので、結構ややこしい。ほとんどの機能ではデータを加工し扱う。


#８、改善点
###・コードが分かりづらい
コーディングが適当で今コードを見てもよく分からない。チーム開発では、クラス名など相談しながら、気を使ってコードを書いていましたが、自分一人だと適当になってしまった。
リーダブルコードを読んだ時、「分かりやすいコードは人のためだけでなく数ヶ月後の自分の為にも」ということが書いてあったが、まさに数ヶ月後の現在の自分は、自分が書いたコードが理解不能であった。

###・保守性がない。
例えば、**「年と月を選択するとカテゴリー毎の金額と全体における割合、そして月の合計額が分かる」**という機能。どうやってデータを引っ張ってきているかというと...

```
#収入計算
    @income_detail_saraly = Income.group("YEAR(date)").group("MONTH(date)").where(income_categories_id: 1, user_id: current_user.id).sum(:amount)
    @income_detail_saraly[[@search_year.to_i, @search_month.to_i]]
    @income_detail_saraly_view = @income_detail_saraly[[@search_year.to_i, @search_month.to_i]]
```
お分かりいただけただろうか。なんとこれは「収入カテゴリーの給与額」のみでこれだけのコード量なのだ。全ての費目を取ってきたらどんなコードになるのか。ここでは載せられません笑

今だったら「for文で回せばいいだろ」「SQL文下手くそだな」とか思うが、当時はデータをなんとか複雑な処理で取ってきたとき嬉しくて、そこで満足してしまった。「とりあえず表示させて見よう。リファクタリングは後からだ」とほったらかした顛末がこれである。

ここでの問題は、**「コードが長すぎる」**ことに加え、重要な点として、もし将来**「ユーザー自身が任意のカテゴリーを追加できる機能」**を実装するとなったら、対応できないということ。なぜなら、上のコードでは全てのカテゴリーを１つずつ直書きしてデータを取ってきているため。

こういう**「一応機能としてはできてるけど、保守性が足りない」**という機能がたくさんある。

###バリデーション
・様々なカテゴリーを作り、ユーザーに入力してもらいますが、値が入っていない場合は￥0を返すようにする。

・予算は一度設定したら、同じ月で入力しようとすると変更画面へ移動させる

などなど、考えだすとなかなか多く、途中で気づくことも多かったです。
恐らく、まだ気づいていないものもありそう。

#まとめ
やっぱり個人でアプリを作ってみるというのは大変で、考えることがいっぱい、途中で色んなことに気づくし、そういえばこれどうやるんだろうと疑問に思うことも多々あります。でも、本を読んで分かった気にならずに、何度も書いてますが**「自分で考える」**ことが何より身になった、と強く実感しました。