経験ゼロの新人が1ヶ月でウェブアプリを作らされるヤバい研修 part 2

Part 1はこちら↓

https://qiita.com/Terao-Takumi/items/d2b02a4cf0470675107e

新人研修の初日2日間で行われた「UX/UI研修」が終了し、いよいよ実際の開発に入っていくことになった。先輩に聞きながら、全体の流れは以下のように決まった。

1)アプリの仕様を細かく詰める(いつお茶会を開催するの? 人数は? どうやってグループを分ける?など)

2)UIはマネージャーがadobeのXDで作成してくれることに

3)仕様が大まかに決まったら、その仕様を満たすことのできるデータベースの設計をする

4)DB作成と最初の環境構築を先輩に助けてもらいながらやって、その後コードをガリガリ書いていく

5)機能ができたら、テスト、テスト、テスト....

6)納期は絶対に変えない

UX/UI研修が終わり仕様を詰める工程に入るにあたって...これは研修では指示されてはいなかったけれど、改めて「どんなアプリにしたいのか?」を自分の中でしっかり考えてみた。

「理想のアプリ」が自分の中にないと、仕様を決める方針がブレたり、下手をすれば自分たちの自己満に終わってユーザーに価値を提供できないかもしれないと思ったからだ。

前職でマーケティングや商品企画、商品制作をやっていたので、エンジニアに転身はしたけれど、マーケターのノリで”商品企画”をやってみることに。

いつも使っているのは、Mac用の「X-mind」というマインドマップアプリ。無料で使えるので、macユーザーはぜひ使ってみてほしい。思考の整理がめちゃくちゃ捗ります。

![スクリーンショット 2022-05-16 16.59.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496677/c24aacef-f317-05ce-0926-e0570989d283.png)


・このアプリは何をしてくれるアプリなのか

・アプリを使う前に抱えている課題はなにか

・アプリを使えばなぜその課題を解決できるのか

・どんなメッセージを伝えれば使ってみたくなるのか

こういったものを考えて、それを仕様に落とし込んでいった。タスクとしては、システムエンジニアがやるようなことなのかな?とか考えていたが、そもそも「プログラマ」とか「SE」とかの違いすらよくわかっていなかったので、今考えるとよくそんな浅い認識でジョブチェンジしたなと思う(笑。

ただ、こういった設計の部分をやるにあたって、マーケターとしての経験は全然無駄になっていないどころか、むしろエンジニアとしての自分の付加価値にもなるなとは思う。プログラミングは全くの未経験だけれど、こういう部分で食らいついていけるなと確信した。

ちょっと余談だったが、自分がこうしている間マネージャーはASAPでUIを仕上げてくれていた。

![スクリーンショット 2022-06-01 5.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496677/577da4dc-96be-9bda-6cb9-1ab5c4eb35de.png)


画面数がめちゃくちゃ少ない(笑)

一番左が、初回アクセス時のページ。ユーザーにやってもらうのは、slackを通してログインしてもらうことだけなので、ほぼLP(ランディングページ)のような形になった。文章は前職でライティングを5年やっていた自分が担当。突貫工事にしては、それっぽいものができた。

あと作るページといえば、ログイン後のhome画面と、お茶会の出欠登録ページのみ。シンプル！

---

## DB設計・新人がハマるところ

仕様をザーッとまとめた後、いよいよDB設計に。使ったツールはUX/UI研修でも使ったlucidというウェブアプリ。

![スクリーンショット 2022-05-16 17.21.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496677/115b7e8d-6243-5bba-ef3a-38e5e2e0c6fd.png)


こんなふうにテンプレートを読み込んだら(SQLニワカでも)ER図をそれっぽく書ける。ぜひ使ってみてください。これは先輩からレビューをもらって修正した完成形。

ざっくり、、、

・ユーザーテーブルにユーザーの登録情報をまとめる

・お茶会テーブルに毎月複数のお茶会情報を作っていく

・参加者名簿でそれぞれのお茶会に参加する人とお茶会を紐付ける(中間テーブル)

・開催日テーブルは、自動でお茶会を作成するときに参照する

最初、お茶会の開催日もプログラム側で動的に作成しようと考えていたので「開催日」テーブルは存在しなかったのだが、

「もし次の開催日をちょっとずらしたいときどうする? プログラムわざわざ書き換えるの?」

「........確かに...」

といったやり取りがあって、開催日テーブルから直近の開催日を取って、お茶会テーブルの開催日に入れたほうがメンテが楽そうだという方針に。**こういった先に起こりそうな問題を事前に(一瞬で)指摘する先輩すげぇ**なーとシンプルに尊敬した。自分も経験を積めばこんなふうになれるのだろうか?

それ以外にもいろいろフィードバックを受けたが、他に印象的だったのは、**NULLを状態管理に使うな!!!**というもの。

参加者名簿テーブルでは、出欠ステータスというカラムで、0なら不参加、1なら参加、NULLなら出欠を回答していない、というふうにNULLに状態をもたせようとしていたのだが、、、

「DB定義を見ないとわからない状態は開発者しかデータベースを見て理解できないからなるべく使わないほうが良い」

というアドバイスをいただいた。確かに…。入力ミスでデータがバグる欠点があっても、ひと目で状態がわかる文字型で管理するのがダイレクト出版のスタンダードだとこのとき知った。

動くプログラムは個人開発でも勉強することは可能だが、こういった設計や命名の技術は個人で勉強していても身につかない。なので、先輩からフィードバックをもらえる環境というのはプログラミングを学ぶ上でとても重要だと、今になって思う。

# いよいよRailsでコーディング

M1 Macを使っているせいで環境構築にハマり1日潰れたが(笑)、RDS上にDBを用意したりdatabase.ymlを設定したりということは全部先輩におまかせして、新人2人は機能の実装に入っていった。

ちなみに、今でこそRDSとかdatabase.ymlは勉強して理解できるようになったが、当時はその単語すら知らなかったので、この設定をするだけで1週間、2週間くらいかかっていたかもしれない。

この研修の目的は、あくまで新人がRailsでコードを書く経験値を積むためのものなので、うまく難易度を調整できている。

機能の優先度を考え、自分はまず根幹機能である「お茶会を作成し、ランダムにユーザーを各お茶会に割り振る機能」を作ることになった。

現場はこんな感じ。
![Image from iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496677/6c7454a2-6744-34e5-450b-cfb901728259.jpeg)



(実際のコード)

```ruby
#以下のメソッドでお茶会をそれぞれ作成する
  def create_teatime_and_list
    active_users = MstUser.where("mus_recess_flag = 0")
    n_of_active_users = active_users.count
    today = Date.today
    future_candidates = MstEventDate.where("med_event_date > ? AND med_delete_flag = 0", today).limit(1).order("med_event_date asc").select("med_event_date")
    future_candidates.each do |future_candidate|
      @next_event_date = future_candidate.med_event_date
    end

    #ここから条件分岐
    if n_of_active_users < 12
      #この場合お茶会は開かない。「今月はなしです」という通知をアクティブユーザーに対して行う
      #このelse以下はつまり、ユーザー数が12人以上のときに対して行う処理
    else
      # お茶会作成

      n_of_teatimes = n_of_active_users.div(4)
      n_of_teatimes.times do |teatime_name|
        teatime_name += 1
        TrxTeatime.create(ttt_event_date: @next_event_date, ttt_teatime_name: teatime_name, )

      end
      #ここまででk個のお茶会が作成された。
      fork_flag = n_of_active_users.modulo(4)
      case fork_flag
      when 0
        random_active_users = MstUser.where("mus_recess_flag = 0 AND mus_delete_flag = 0").order("RAND()").pluck(:mus_user_id).to_a
        list_of_teatimes = TrxTeatime.where(ttt_status: "checking").pluck(:tpl_teatime_id).to_a
        #ユーザー配列ではa+1番目からb個の値を取り出す。お茶会配列ではc+1番目の配列を取り出す
        a = 0
        b = 4
        c = 0
        n_of_teatimes.times do
          lists = random_active_users[a, b]
          teatime_id = list_of_teatimes[c]

          lists.each do |list|
            creation = TrxParticipantList.new(tpl_user_id: list, ttt_teatime_id: teatime_id)
            creation.save
          end
          #次の「n_of_teatimes.times do」処理のためにオフセットの場所を切り替える
          a += 4
          c += 1

        end
      when 1..3
        random_active_users = MstUser.where("mus_recess_flag = 0 AND mus_delete_flag = 0").order("RAND()").pluck(:mus_user_id).to_a
        list_of_teatimes = TrxTeatime.where(ttt_status: "checking").pluck(:ttt_teatime_id).to_a
        #ユーザー配列ではa+1番目からb個の値を取り出す。お茶会配列ではc+1番目の配列を取り出す。4人のお茶会がd個できる。
        a = 0
        b = 5
        c = 0
        d = n_of_teatimes - fork_flag

        #最初に5人グループをつくる。
        fork_flag.times do
          lists = random_active_users[a, b]
          teatime_id = list_of_teatimes[c]

          lists.each do |list|
            creation = TrxParticipantList.new(tpl_user_id: list, tpl_teatime_id: teatime_id)
            creation.save
          end
          #次の「fork_flag.times do」処理のためにオフセットの場所を切り替える
          a += 5
          c += 1

        end

        #先に取り出すユーザーの数を4つと決める。
        b = 4

        d.times do
          lists = random_active_users[a, b]
          teatime_id = list_of_teatimes[c]

          lists.each do |list|
            creation = TrxParticipantList.new(tpl_user_id: list, tpl_teatime_id: teatime_id)
            creation.save
          end
          #次の「fork_flag.times do」処理のためにオフセットの場所を切り替える
          a += 4
          c += 1
        end

      end

    end
```

動くかどうか、という観点で見れば、経験ゼロにしては1日でよく書けたと思う。が、、、

まず命名がヤバい(笑)

aとかbとか、わからせる気ゼロな変数が至るところで使われている…。

```ruby
creation = TrxParticipantList.new(tpl_user_id: list, tpl_teatime_id: teatime_id)
creation.save
```

これなんかも、ヒドい命名…。また、newしてsaveするのかcreateするのかの取捨選択も全然できていなかったなーと、今思うと恥ずかしくてあまり人様に見せたくない(笑)

コメントも謎。メソッド長すぎ。

プログラマーは過去に自分が書いたコードを見ていろいろ思うところがあるそうだが、4ヶ月前の自分から今の自分が着実に成長しているなとポジティブに捉えることにする。

# 順調に機能とViewができていく。が…

ややこしかったのは最初の機能だけで、あとはサクサク実装できた。全体のスケジュールは4日分巻いているという。

1ヶ月でできるのか!?と思っていたが、動作するアプリは2週間でできてしまった。

これは時間余るなーということで、この後少し方針転換するのだが、それがある悲劇を生み出してしまうことを、このときの自分はまだ知らない…。

↓part 3はこちら↓

https://qiita.com/Terao-Takumi/items/dade773928422ee7052b