フィヨルドブートキャンプを卒業しました!

プログラミングスクールのフィヨルドブートキャンプ(以下FBC)Railsエンジニアコースを卒業しました。作業時間1762時間、期間にして2年4ヶ月かかりました。内訳はチーム開発まで1年1ヶ月、チーム開発4ヶ月、自作サービス11ヶ月でした。

月ごとの振り返りをサボっていたので総括として振り返りつつ、入会を迷っている方や現役生に何か参考になればと思ってどんな風に進めていたのか書いていきます。

雰囲気を見て入会を決めた

入会検討の経緯

FBCに入る前はプログラマー適性を見るためにProgateで学び始め、その後Railsチュートリアルを学習し終えた状態でした。適性はありそうだと判断して未経験での就職を視野に入れましたが、就活に必要なポートフォリオを作成するのに独学で頑張るかスクールに入るかの選択を考えることになりました。当時の最新verのRails7の教材が少なく「パーフェクトRuby on Rails増補改訂版」を買って読もうとしてみましたがRailsチュートリアルの知識だけではなかなか難しく、独学よりもスクールが良いのではと思い始めました。

プログラマーをしている知人に相談してみたところFBCともう一つのスクールを提案されました。両方調べてみてFBC生のブログやFBCのYouTubeなども見てFBCの雰囲気が良さそう、というくらいの印象でFBCのお試しを始めました。

お試しで感じた雰囲気の良さ

入会するときにアンチハラスメントポリシーに同意する必要があり、まずそこでハラスメント防止を明文化して気をつけようという姿勢を見せていることが印象的でした。また、Discordで自己紹介をしたり初めての日報を書いたりした後歓迎のリアクションをたくさんいただけて、コミュニティとしてのFBCを大事にしていることが伝わりました。

普段SNSは見る専なのでコミュニティ参加を求められることに若干戸惑いはありましたが、初めての日報にメンターさんから丁寧な口調でコメントをいただけてメンターさんにも対等な立場で接してもらえそうと思ったこと、カリキュラムの内容が良さそうだと感じて入会を決めました。

ゆるい繋がりに支えられた

コミュニティ参加はほどほどだった

初めの方のプラクティスで他の受講生とのつながりが大事という内容がありますが、自分は積極的にはコミュニティに参加していませんでした。チーム開発前は日報にいただいたコメントにスタンプや返信コメントでリアクションする程度で、その他は提出物についてレビューアーのメンターさんに質問することがあるくらいでした。

ただチーム開発が始まるとkomagataさんと他の受講生の方とカメラオンでミーティングをする必要が出てきました。初めは緊張しましたが、ミーティングで、特にカメラオンで交流したことがその後もkomagataさんの質問タイムで質問しやすくなったきっかけになりました。自作サービスでは週一の進捗報告会で他の方の進捗を見たり、メンターさんにアドバイスをもらったりして緩いつながりを維持できたことが今思えば心の支えになっていた気がします。

FBCコミュニティにもっと参加したい人にもDiscordの作業部屋や輪読会などその手段がありますが、自分のペースで参加したい人にも寄り添った設計になっていると思います。

日報は自分のためにも人のためにもなる

どうやって毎日日報を書いていたか

地味に大変なのが毎日日報を書くことでした。元々文章を書くのに時間がかかるタイプなのでハードルを下げるために「今の気持ち」欄は何かしら書ければ良いことにしていました。自分は一日の最後に日報を書くのではなく作業時間を記録しながら思いついた時に内容を埋めていって最後に提出するというスタイルで進めていました。

やって良かったこと

自作サービス着手からは参考にしたサイトのURLを載せることにしていました。これによって何のサイトを参考にしたか後から見返したり、同じような実装をするときにまた参照するということが楽になりました。時々参考にしたサイトをメンターさんから聞かれることがあったのでその確認にも良いと思います。

参考にしたサイトをメンターさんに聞かれることがあるのでできるだけ公式ドキュメントなど信頼できる情報を探そうと意識するようにもなりました。

面倒くさがってURLを貼っただけにしていたので、何の参考にどのサイトを使ったかまで書いておけばもっと役に立ったかもしれないと振り返って思います。

日報制度の良さ

日報制度の良いところは詰まった時に直接の答えにならない程度に他の方の学習を参考にできたところにもありました。サイトURLが載っていればそれも参考になるし、学習した内容を書いている方も参考になりました。

自分も自作サービスでやったことをメモ的に残した日報を参考にしてもらえて嬉しかった出来事がありました。

入って良かったこと

カリキュラムが決まっている安心感

カリキュラムが決まっていて、参考にするべき書籍も指定されている、という点が迷わずに学習していけるのが楽で良いなと特に初めは思っていました。自分はProgateやRailsチュートリアルを先にやっていましたが、特に何も触ったことがなくてもできる難易度から始まるのでそこも心配はいらないです。設定されているカリキュラムを一通り理解してこなせば就職できるレベルに到達できるという安心感のもと学習していけます。

またコーディングだけではなく周辺知識も含めて体系的に学べたことも良かったポイントでした。

実務レベルのチェック体制

一番大きいのはメンターさんの存在だと思います。rubocopのようなツールのルールにはないけどこういう書き方をする場合が多い、というものがとにかく多いのでそれを教えてもらうだけで他の人が読みやすいコードに一歩近づけると思います。

自作サービスでは自分では一応納得した状態でコードレビューに出しましたが、かなり修正点がありました。他の人が読んでわかりやすく修正が容易なコード、無駄がないのに要点を抑えられるテストの書き方を徹底的に教えていただき実務レベルのコードとはどういうものかという視点をもらえました。自力で習得するのも不可能ではないと思いますが、そのスピードが段違いなのではないでしょうか。

コーディングだけでない自作サービス開発

自作サービスでは自分で考えたもの、またはFBCで用意されたテーマのサービスを一から作ります。画面の構成やサービスの仕様も自分で考えなくてはいけません。もちろんメンターさんに相談することはでき、手戻りが少なくなるよう作る前にチェックが入りますが、自作サービス開発のテーマとして今の世の中に存在していないサービスで代替手段よりも優れたもの、つまり本当に必要とされるものを選定する必要があります。

チーム開発までは用意された課題をこなす、あるいはIssueを解決する学習方法でしたがここで一気にプログラマーとしてだけでなく企画やプロダクトの責任者、デザイナー的な役割までこなす必要が出てきます。自分はFBCで用意されたテーマにしたのでサービスの根幹的な仕様は発案者からヒアリングして決定しましたが、UXを考えたプロダクト作りを行う経験はそれまでのカリキュラムとはまた別の面でとても勉強になりました。

最後に

FBCでの2年4か月を振り返ってみるとモチベーションの波もあったし、卒業までの目安時間1000時間というのを見て入ったのに全然終わらないんだけど…!と思うこともありました。それでも地道に作業を進めて日報を書いてミーティングに参加して、という習慣を崩さなかったからこそ最後まで完走できたのだと思います。

FBCはコツコツと進める人を裏切らない場所です。今カリキュラムに詰まっている現役生の方もいらっしゃるかもしれませんが、ぜひ自分のペースを信じて継続することを大切にしてください。

FjordBootCamp関係者向けのクローズドなフリマサービス「FjordStand」をリリースしました

はじめに

2024年3月からフィヨルドブートキャンプ(以下FBC)でプログラミングを勉強してきたkussyと申します。

不用品をFBC内の人に安く譲って役立ててもらいたい人が、クローズドな環境で商品を出品できるフリマアプリをリリースしました!FBCでの学習を終えた参考書や、買い換えて使わなくなったガジェットなどをFBCの仲間に譲り合える場所としたい!という思いで開発しました。

FjordStandのロゴ

サービスURL

fjordstand.com

サービスリポジトリURL

github.com

目次

サービスの紹介

FjordStandとは?

FBCのDiscordサーバーに参加しているアカウントを使ってログインし、ユーザー同士で商品を出品して購入希望を申請できるフリーマーケットプレイスです。

サービスの特徴として一般的なフリマアプリとは異なり先着順に購入が決定するのではなく、自動抽選で購入者が決まります。購入希望の申請締切を設けて出品するため、タイムラインに張り付く必要がなく、締切までの間に申請ボタンを押すだけで公平にチャンスがあります。

使い方

ユーザー登録

ユーザー登録にはFBCのDiscordサーバーに参加しているDiscordアカウントが必要となります。

「Discordでログイン」ボタンをクリックし、アカウントを選択してください。

ログインボタン
ログインボタン

出品

ヘッダーの「出品する」ボタンをクリックし、商品情報を入力してください。購入希望申請締切は選択した日付の23時59分に設定されます。

出品後は商品名・商品説明・お支払い方法の変更と締切日の延長のみ行うことができ、画像の削除や価格と送料負担の選択を変更することができません。

下書きとして保存した場合は全ての項目を変更することができます。

出品ボタンと下書き保存ボタン

購入希望の申請

商品詳細ページの「購入希望を申請する」ボタンから購入希望の申請を行うことができます。

取り消したい場合は申請後に同じ場所に出現する「購入希望を取り消す」ボタンから行ってください。

商品詳細ページ
商品詳細ページ

締切日を過ぎると自動で希望者の中から抽選が行われ、購入者が決定します。抽選は毎日8時頃に行われます。

コメント

商品詳細ページからコメントを投稿することができます。

商品のコメント欄
商品のコメント欄

出品者とコメント投稿者は自動的に商品をWatchした状態になり、新しいコメントが投稿された際に通知を受け取ることができます。Watchを外すには「Watch中」ボタンをクリックしてください。

出品者およびコメント投稿者でなくても気になる商品は「Watchする」ボタンをクリックすることで通知を受け取り、Watch中一覧を活用することができます。

出品者と購入者の連絡

連絡ページから出品者と購入者で送金先や商品の発送先を連絡し、外部のサービスを使って送金および商品の発送を行ってください。

連絡ページは出品者と購入者(および管理者)以外には非公開なため、プライバシー面でも安心して連絡を行うことができます。

連絡ページ
連絡ページ

技術スタック

カテゴリ 技術
バックエンド Ruby 4.0.5 / Ruby on Rails 8.1.3
フロントエンド TailwindCSS / Hotwire (Turbo + Stimulus)
データベース PostgreSQL
バックグラウンドジョブ Solid Queue
認証 Discord OAuth (OmniAuth)
テスト RSpec / Capybara
インフラ Kamal / さくらVPS
CI / CD GitHub Actions

工夫した点

ユーザーがストレスなく安心して操作できるUX/UIを意識して画面の設計を行いました。

下書き機能

商品を出品するにはいくつもの項目を入力しないといけないため、途中で離脱できるように下書き機能を追加しました。公開時のみ商品名などの必須項目のチェックが走るステータス管理の仕組みを設計に取り入れました。

商品画像のプレビュー機能

デフォルトの状態ではファイル選択時にファイル名しか表示されず、どの画像を選んだか直感的に分かりづらい状態でした。Rails標準のJavaScriptフレームワークであるStimulusを活用し、リロードを挟まずにその場で選択した画像を表示・削除できるプレビュー機能を実装しました。

開発で苦労したこと

技術検証の段階で想定していた処理から、実装フェーズになって大きく設計を変更した機能がありました。

Discord通知におけるDMからWebhookへの変更

DMチャンネル開通処理における問題の発覚

技術検証の段階ではアプリ内通知と同じようにパーソナルな通知でかつリアルタイムに気づけるものを想定してDiscordのDM(ダイレクトメッセージ)をBotから送るという通知方法を構想していました。実際にBotからDMを送れるということまでは確認していたのですが、実装段階で改めてDiscord APIの公式ドキュメントを読み込んだところ、重要な注意書きに気がつきました。DMで一度もやり取りをしていない相手に対してDMチャンネル開通のAPI(create DM)を叩くという処理を何度も行うとAPIのレートリミットに引っかかるというだけでなくブロックされる可能性があるというものでした。

DMからWebhookへの転換を促したアドバイス

DM開通処理の問題を解決する方法として考えたのは、DM通知を希望するユーザー側から一度Botに対してメッセージを送ることでDMチャンネルを開通させ、Botから直接メッセージを送る(create Message)ことができるようにするということでした。実際にBotに対して一度メッセージを送ることでチャンネル情報をアプリに登録し、Botからメッセージを送信できることを確認できました。しかし、通知を受け取るためにユーザー側からアクションを起こさないといけないという点がUXの観点から引っかかっていました。そこで、自作サービス進捗報告会で駒形さんと町田さんに相談したところ、ユーザーに手間を強いるDMではなく、サーバーにWebhookを設置し、そこにメンションを付ける形で通知してはどうかとアドバイスをいただきました。メンションが付けば、通知の気づきやすさはDMと変わらないという提案でした。

Webhook実装の決定

Discordで通知する内容として抽選の当落通知や非公開の連絡ページでのメッセージの受信などはパーソナルなものであるべきではないかと思い少し迷いましたが、当落通知などにメンションがたくさんつけばそれだけ注目度が高いことが分かって盛り上がるという意見に納得しWebhookでの実装に変更することに決めました。実際に実装してみるとアプリのログインにDiscordによるOAuth2認証を採用しているためDiscordのuid(ユーザーID)を必要とするメンション機能と相性がよく、スムーズに実装することができました。さらに個別に何度もAPIを叩くDMとは違い、メッセージ自体は一通にまとめつつ複数のユーザーに同時にメンションを送れるためドキュメントで言及されていたレートリミットの心配もなくなりました。

定期実行の抽選処理におけるCronからSolid Queueへの変更

本番環境でCronが動かないトラブル

技術検証の段階では、Kamalを使ってさくらVPSにデプロイするという前提で、Linuxと相性の良いCron + Whenever gemを使って定期実行の抽選処理を回そうとしていました。Mac上のローカル開発環境ではCronを使った抽選処理は問題なく動いていましたが、アプリの全体が出来上がってきてデプロイした後、本番環境でCronが動いていないことに気がつきました。

エラーの解消と本質的な問題の理解

KamalでCronジョブを実行する設定をするために参考にしたサイトにはjob_templateの項目が載っていなかったので初めは何も記載していませんでしたが、コンテナ内の設定内容を出力してみるとWheneverがローカル環境(Macのzsh)を引き継いで、zshを使う設定ファイルを生成していたことが判明しました。そこで、job_templateを修正してbashで動くように設定し、本番のコンテナ内でwhenever --update-crontab(設定ファイルの更新コマンド)を実行してみました。しかし、今度は設定を書き込むためのファイルが存在しないというエラー(No such file or directory)が出てしまいました。手動でファイルを作成して登録自体は成功したものの、やはり抽選処理は動かず、詳しくログを追うと今度はコンテナ内のCronプロセスへ必要な環境変数が渡っていないことが判明しました。よく調べてみると、そもそもDockerコンテナ内でLinuxのCronを動かすには、パッケージのインストールや環境変数の受け渡しなど、複雑なインフラ設定をする必要があるようでした。また、ネットのインフラ解説などを見ると、Docker管理の基本的な考え方としては1機能1コンテナを使い、既存のコンテナにCronジョブを動かすための設定を追加するより、専用のDockerコンテナを新規で切り出すか、AWSのサービスなどを利用してコンテナの外からジョブを実行するべき、という記述もありました。

Solid Queueへの転換のきっかけ

原因究明に時間がかかったと書いた日報に対して駒形さんから「cronでコマンド動く時って環境が違ってたり、エラーが分かりづらかったりしてなかなか面倒なんですよね〜」というコメントもいただき、やはりCronよりも良い方法を模索するべきではと考え始めていました。そんな折、自作サービス進捗報告会で他の受講生の方が定期実行ジョブをSolid Queueで行っているということを知ってCronではなくSolid Queueで抽選を行えないか試してみることにしました。

抽選処理と通知処理への適用

Solid QueueはRails 8の標準機能でありWebサーバーと同じコンテナ・プロセス内で定期実行ジョブを実装できるという特徴があります。実際にSolid Queueで抽選処理を実装してみると課題になっていた環境変数の受け渡しは気にする必要がなくなり、Pumaのマルチスレッドを活かした実装のためコンテナを切り出す必要もありませんでした。さらにSolid Queueを導入したことでシステム全体の設計を大きくリファクタリングする機会が生まれました。それまでDiscordでの通知はユーザーの操作と同じタイミングで同期的に処理していました。しかし、外部APIを叩く処理は通信環境によっては時間がかかってユーザーを待たせてしまう可能性がありました。そのため、定期実行のために導入したSolid Queueを活用し、Discordの通知処理も非同期のバックグラウンドジョブとして実行するようにコードをリファクタリングしました。

ジョブ管理の効率化

また、mission_control-jobs gemを導入したことでログを見に行かなければ分からなかったジョブの実行ステータスやエラーがブラウザ上で確認できるようになりました。これで「エラーが分かりづらい」という問題点もRailsの機能だけで克服することができました。エラー発生時に専用のDiscordサーバーに送られるように設定したWebhook通知と合わせてより簡単にエラーを発見・再実行できるシステムを作ることができました。

振り返って

今回のDiscord通知(DMからWebhookへの変更)と定期実行の抽選処理(CronからSolid Queueへの変更)という2つの大きな転換で共通する反省点と学びがありました。技術検証の段階では「ローカル環境で機能が動くかどうか」という点を重視してしまい、本番運用における外部APIの規約やリスク、ユーザーの手間、そしてDocker環境という構造的な制約への想像力および調査が不足していたということです。

しかし公式ドキュメントを読み込んだりデバッグを繰り返してエラーの根本原因を突き止めたりした経験を経て、メンターや他の受講生の知見を借りて現在の環境で最適と思える実装へ納得して転換することができました。遠回りの実装にはなってしまいましたが、この経験から単に機能を実現するコードを書くのではなくアプリケーションが動くインフラ環境やユーザー体験とのトレードオフ、運用(デバッグ)のしやすさなどを総合的に考えた技術選定を行う重要性を学ぶことができました。

今後の展望

フリマアプリとしての使いやすさをさらに向上させるため、下記の改良を加えることを考えています。

  • Watch中商品の締切前のリマインド通知:欲しかった商品をWatchしたものの実際に希望申請し忘れていた、という事態を防ぐ機能です。Watch中かつ未申請のユーザーに対してDiscord上でメンションをつけた通知を行います。
  • 一覧ページの並び替え機能:現在は並び順が固定されている販売中・Watch中・希望商品・自分の商品といった一覧ページですが、目的の商品をすぐに見つけられるように締切順や新着順に並び替えることのできる機能です。

最後に

自作サービスの着手から約11ヶ月かかってようやく完成を迎えることができました。日報にコメントをいただき質問にも答えてくださった駒形さん、アプリの設計相談に乗ってくださり、デザインについてもかなり改善案を出してくださった町田さん、丁寧にコードレビューしてくださりコードの品質を高めるアドバイスをくださった伊藤さんをはじめフィヨルドブートキャンプの皆様に感謝申し上げます。

最後までお読みいただきありがとうございました。

FBC 10月振り返り

やったこと

取り組んだ日数は16日間で時間は約80時間だった。「リソース・データ設計」から「Webサービスを作る」の途中まで進んだ。今までの総時間が約1230時間になった。

振り返り

  • 1日あたりの取り組んだ時間が多めだった。自作サービスが順調に進んでいたので長時間取り組めた。ただ月末になって少し失速した。
    • 失速したのは細かいところが気になって時間の割に完成度が高まっていないのがやる気低下につながっているかもしれない。大事な機能を先に実装してから細かいところに取り組んだ方が良い気がする。

感想

順調に進んでると自作サービス楽しいと思えるのに、ふと、ネットで見つけたコードの真似ばっかりで自分がこれを作っている意味って?とか就活まで行かないといけないのに完成までに何ヶ月かかるんだろうとか思い始めると一気に気持ちが落ち込んでしまう。

FBC 8、9月振り返り

やったこと

取り組んだ人数は8月は12日間で時間は約30時間、9月は16日間で約50時間だった。「どんなサービスを作るかを考える」から「リソース・データ設計」までやった。今までの総時間が約1150時間になった。

振り返り

  • 8月9月ともに取り組んだ日数、時間が少なかった。朝起きられなかったりやる気が出なかったりで始める時間が遅かった。
    • 始めてしまえばそのあとは集中して取り組めたりするので始める時間を決めておくのが良いかもしれない?

感想

技術検証でアプリ実装の道筋はなんとなく掴めているので8月時点ほど不安はないが、なんとなく気が乗らないのはなんでかよく分からない。

FBC 7月振り返り

やったこと

取り組んだ人数は19日で時間は約55時間だった。「開発に参加してPRを送りマージする」がほぼ終わって「どんなサービスを作るかを考える」に入るところまで来た。今までの総時間が1065時間になった。

振り返り

  • 取り組んだ日数・時間ともに前の月と同じくらいだったが全体的に少なかった。チーム開発の作業が終わって一息つきたかったのもあるが、自作サービスでどんなことを実現できるか見えてこなくて始められなかったのもある。
    • テーマはFBCで提案されているものにしようかと考えているので、技術的なことはメンターさんに相談できると思ってやり切ることを目指して初めてしまった方が良さそう。不安があるならそれも相談する。
  • 企業説明ドリンクアップに参加した。自社開発のところも受託開発のところの企業説明も聞けたので雰囲気は分かって良かったが、あまり良い質問はできなかった気がする。
    • 就職相談も始めよう、というフェーズに来ているのでどういうところに企業ごとの違いが出るか、みたいなことも含めて相談してみると良いかもしれない。

感想

自作サービスも就活相談も不安な点が多くて憂鬱…。とりあえず就活はポートフォリオが必要だと思うので自作サービスを完成させることを目標に、週1のMTGを使ってテンポよく開発できるようにしていきたい。

FBC 6月振り返り

やったこと

取り組んだ人数は17日で時間は約55時間だった。「開発に参加してPRを送りマージする」の途中。今までの総時間が1000時間。

振り返り

  • 取り組んだ日数・時間は前の月と同じくらいだが、後半で失速した感じだった。よく分からないIssueがあってやる気が落ちていた。
    • よく分からないことがある時は早めに質問する。
  • LT会にラジオ参加した。他の受講生の話を聞く機会がなかったので新鮮だった。
    • 今まで全然コミュニティのイベントに参加していなかったのでミートアップのアーカイブを見るところからでもラジオ参加でもいいのでもう少し参加していきたい。

感想

FBCの目安の1000時間を超えたがまだチーム開発で個人開発が控えているのでなかなか終わりそうにない。ただチーム開発は終わりが見えてきているのでもう少しで終わると思って頑張りたい。

FBC5月振り返り

やったこと

取り組んだ人数は17日で時間は約60時間だった。「開発に参加してPRを送りマージする」の途中。今までの総時間が950時間。

振り返り

  • 取り組んだ日数・時間は4月と同じくらいだった。3・4週目は1日あたりの取り組み時間が長かったがその後少なくなってしまった。
    • 作業に行き詰まってきていた感じなので質問すればよかったかも。

感想

仕事なら分からなかったらすぐ質問するべきだと思うが学習なのでどこまで自力でやってから質問するべきかよく分からない。