自転車とプログラミング

自転車メーカーに勤める会社員がプログラミングを学ぶ中で感じたことを書きます。最近サービス作りました。

paizaスキルチェックにチャレンジ! / Rubyの文字列マッチの文頭文末指定

こんにちは、Watanabeです。

就活的なところを見据えて競技プログラミングにチャレンジ!とpaizaを触り始めました。 触る前にすこし調べてみましたが、競技プログラミングは日本国内だと「AtCoder」の地位が圧倒的っぽい。

paizaは有料プログラミング学習サイト~エンジニア就職のビジネスモデルの一環で、スキルチェック的な立ち位置で運営されているようですね。 競プロ的なスキルチェック問題を解くと、アカウントのステータスやランクが上がってどのレベルのエンジニアかわかるようになっていて、求人を出している企業はそれをもとにスカウトもできたりするみたいです。面白いビジネスモデル👀

AtCoderよりもpaizaのほうがとっつきやすくて始めやすかったので、paizaを触ってます。いずれはAtCoderも触ってみて比較の記事を出せたらいいね。

paizaの流れ

paizaの中でいくつかコンテンツがあって、paizaラーニングが学習、レベルアップ問題集が模擬、スキルチェックがテスト(競プロ)の立ち位置になっています。

今回チャレンジしているのはレベルアップ問題集とスキルチェック。どちらもpaiza内のエディタで与えられた条件を満たす処理をコーディングしていく流れです。導入解説はオフィシャルに動画コンテンツが用意されています。手厚くて好印象。

paizaのエディタ

主要な言語はカバーされていて、入力補完もされるので良い感じでした。 コーディングして提出すると用意されたテストケースに沿ってテストが実行されて、それが通り具合で点数がでます。

今のところは最低レベルのDを恐る恐る触っています。Dでもちょっとひねりをきかせた問題がでると「あれ…?」とフリーズしてメソッドなんかが出なくなってしまったので要訓練です。

「RubySilver取ったんだけど全然だなー」とは思ったりしますがあっちは選択問題で、paizaはコーディングなのでより理解度が試されてますね。

文字列マッチング時の文頭と文末の指定

これもRubySilverでやったのにでてこなかったやつ。条件を満たせずに数点落としました。

"Ruby".match("^Ruby$")
#=> true 
#=> ^は文頭、$は文末をRubyの正規表現で表す

初歩も初歩なのですけどねー。何も見ずだとなかなか出てきませんでした。 他の基礎的な正規表現も復習しておきます。

  • .: 任意の1文字とマッチ
  • *: 直前の文字の0回以上の繰り返しとマッチ
  • +: 直前の文字の1回以上の繰り返しとマッチ
  • ?: 直前の文字の0回または1回の出現とマッチ
  • []: 文字クラス。括弧内の任意の文字とマッチ

社内勉強会を開催してきた経験をもとに盛り上がるテーマについて考えてみた

こんにちは、Watanabe です。

ここ2〜3年の間でいくつかの勉強会を立ち上げたり、単発で開催してきました。 エンジニアの知識をシェアするスタンスに感銘を受けたことが根っこにあって、自分の職場でも共有知を作って組織のレベルを底上げしていければ、ゆくゆくは各メンバー発の情報共有が進んでほしいと思ってました。

盛り上がるテーマとは?

勉強会を開催していて永遠の課題といっていいと思いますが、勉強会で盛り上がる回と盛り上がらない回がありませんか? 開催する側としては参加した人が得るものが多い勉強会で有りたいと思っていて、その方が持続的に勉強会が開催できますし、組織に知見が蓄積されやすくなります。そういった得るものが多い勉強会にするためには、勉強会が盛り上がることは不可欠じゃないかなと思います。

体感として盛り上がることが多かった勉強会に共通しそうなところを挙げてみます。

参加者のレベルが均一している

参加者のレベルが同じ程度だと安心してディスカッションができるっぽく、盛り上がる気がします。レベルの高い人も低い人もその人自身はつまらない会になるリスクがありますし、レベルの高い人がいると「まちがったこといいづらいな〜」と萎縮する人がいてディスカッションがはかどりませんでした。

ノルマが優しめ

ノルマが厳しいと企画倒れになりますね(経験談)。なのでエンジニアの方が読書会をノルマ付きでやられてるのはすごいと思います。ノルマを課して、うまく回ると参加者も準備してくるので勉強会が自分ごとになって盛り上げてくれますね。

意見を交わすことができる

ディスカッションタイムを設けるのは盛り上がる会を作る上で大事ですね。ディスカッションさせるなら自分がハンドリングする必要はありますが。

参加者が熱中できるテーマである(参加者の熱量とテーマのレベルが合致している)

「参加者のレベルが均一」の話と近いですね。テーマと参加者のレベルが離れていると盛り上がりに欠けます。テーマに合った参加者に参加してもらうように働きかけるのも企画者のタスクですね。このあたりは企画して実行するだけじゃなく、当日現場が盛り上がるように根回しは必要かと思います。


ここらへんをカバーできていると現場で盛り上がることが多いかなと勉強会を主催していて思います。

反対に盛り上がらなかった勉強会としては、「読んだ本を紹介する会」というのを開催していたんですが、毎週開催と発表者が紹介制・本を読む人が少ない会社だったことが重なって早々に企画倒れになりました。環境と人にミスマッチなテーマだったと今になって思います。

面白かったのは読んだ本の紹介ができなくなってもプレゼン形式で自己の経歴を紹介する会としてしばらくの間はこの企画が続いて、普段の業務からは知れないその人の人生、考え方を知れる場になったことですね。これはこれで自己開示の場になったのでその後の業務がちょっぴり円滑になった気がします。

初OSS活動に取り組んで得た知見

こんにちは、Watanabe です。 昨年の話になりますがJavaScriptのライブラリにpull requestを送って承認されたことがありました。OSSへのコントリビュート(貢献)できた経験をまとめないのはもったいないのでこちらにまとめておきます。

textarea-markdownにpull requestを送ってマージされました

HTMLのテキストエリアをマークダウン記法に対応させるJavaScriptライブラリtextarea-markdownに新機能をpull requestしました。 経緯としてはFJORDBOOTCAMPのチーム開発にて、FJORDBOOTCAMP内のテキストエリアにファイル選択ダイアログに対応したファイルアップロード機能を追加させるIssueを担当したことから、実装を遡った結果このライブラリに行き着きました。

もともとtextarea-markdownはテキストエリアへのファイルドロップでのアップロードに対応してましたがファイル選択ダイアログでのファイルアップロードには対応していなかったので、オプション的に機能させるように実装しました。

textarea-markdown ライブラリはこちら

通常時はテキストエリアに所定のIDとClassを設定するとtextarea-markdownが反映されます。以下のような感じです。

<textarea id="editor" data-preview="#preview"></textarea>
<div id="preview"></div>
import TextareaMarkdown from 'textarea-markdown'
document.addEventListener('DOMContentLoaded', () => {
  const token = document.querySelector("meta[name=\"csrf-token\"]").content;
  const textarea = document.querySelector('#editor');

  new TextareaMarkdown(textarea, {
    endPoint: '/api/image.json',
    paramName: 'file',
    responseKey: 'url',
    csrfToken: token,
    placeholder: 'uploading %filename ...'
  })

これをオプション的にファイル選択ダイアログに対応しました。 テキストエリアとは別にinput要素を用意し、こちらにもClassを設定してテキストエリアと紐付けることでアップロード(とtextarea-markdownでのプレビュー)が可能になります。

<h2>Editor & File input</h2>
<input type="file" class="data-input">
<textarea id="editor" data-preview="#preview" data-input=".input"></textarea>

<h2>Preview</h2>
<div id="preview"></div>
import TextareaMarkdown from 'textarea-markdown'

let textarea = document.querySelector('textarea');
new TextareaMarkdown(textarea);

中身的にはinput要素を捕捉して

  setInputElement() {
    const selector = this.textarea.getAttribute("data-input");
    if (selector) {
      return document.querySelector(selector);
    }
  }

イベントを設定してファイルが選択されたらアップロード処理が走るようにしています。

    if (inputelement) {
      inputelement.addEventListener('click', (e) => e.target.value = '');
      inputelement.addEventListener("change", (e) => this.input(e));
    }

ドロップファイルでのアップロードが実装されていて主要な処理はすでにあったので、コードリーディングを主に取り組んだ形ですね。 あとこの機能についてREADMEに追記したりもしました。

github.com

OSS活動に取り組んで得た知見

コントリビュートする流れがあって自然とOSS活動に至ったのですが、じつはこれの一個前に同じライブラリに不具合修正のプルリクを送っていました。日本語で。

その時にはマージされましたが「英語で書いてね」とたしなめられてしまって、しまったと思いました。マージされたプルリクは当たり前ですがライブラリの一部としてライブラリが継続する限りはその一部になるのでいつ誰が遡って見るかもわかりません。そのときに「できるだけわかりやすくする」配慮がもとめられると気が付きました。

↑のプルリクはその反省を活かして英語で記述しています。 deepl翻訳やChatGPTを使うことで比較的簡単に英語での文章が作ることができました。日→英、英→日の翻訳をかけて内容のチェックもすればより精度が高いと思います。

また、OSS活動ではIssueを作っての改善内容の提案とプルリクでの具体的な改善提案の2種類があると思いますが、「できるだけわかりやすくする」この方針で考えれば具体的な修正案が伴っていたほうがニュアンスが伝わりやすく開発者や他のコントリビュータにとっても伝わりやすいのかなと思いました。

Ruby Silverに受かりました。学習と試験のポイントまとめ

2024年2/17 更新

こんにちは。Watanabeです。 先日Ruby Association Certified Ruby Programmer Silver version 3(いわゆるRuby Silver)に合格したので、学習方法や対策、感想を書こうと思います。

なぜ受けようと思ったか

RailsWebサービスを立ち上げているにも関わらず、Rubyまわりの知識不足を大いに感じていたのでポートフォリオ強化も兼ねて受けました。

WEB上の情報を調べたところ大体勉強時間30時間〜50時間くらいで合格した話が多かったので自分でもそのくらいでいけるでしょと2週間で試験を受けることにしました。

試験の内容

基本的なリテラルの文法とString, Array, Hash, File, Dir, IOクラスの組み込みライブラリがよく出題されていました。あとはメソッドが破壊的な処理かどうかは頻出でしたね。このあたりを抑えるだけで70〜80%くらい取れるんじゃないかなって思います。

試験問題そのものは詳細には思い出せないですが教本やGitHubの模擬問題と同レベルの問題がほとんどでした。逆にRExまでいくと難化し過ぎであまり実際の試験対策としては役に立たないように思いました。

勉強時間

30時間〜40時間くらいでした。

勉強方法

教材

[改訂2版]Ruby技術者認定試験合格教本(Silver/Gold対応) Ruby公式資格教科書

[改訂2版]Ruby技術者認定試験合格教本(Silver/Gold対応) Ruby公式資格教科書

Ruby SilverとGoldの試験範囲を網羅的にカバーする公式教本です。何においてもこれを優先して取り組むべきです。 演習問題と模擬が付属していてそれらの問題がだいたい本番の試験と同形式になっています。

使いにくい部分が多少あって、ひとつはSilverとGoldの範囲が一冊の中で混ざり合っている点です。明確に区別できるものではないのでしょうがないところですが、試験範囲かと思ってたらそうでなかったみたいなことがありました。 もうひとつが内容が古いという部分です。現行のRubyと当時とで仕様が異なり、解説が間違っていることがあります。私が気づいただけで2〜3箇所は少なくともありました。学習の後半はRubyリファレンスマニュアルを片手に調べながら学習してました。

公式受験対策資料(模擬問題集)

模擬問題集(Silver試験用)がオフィシャルに公開されています。教本付属の模擬問題集と同形式でver3対応版、丁寧な解説付きです。教本模擬と同じく試験と同形式の問題が多く出されているのでこの問題集もマストで取り組むべきです。

REx

Rexはリバティフィッシュ株式会社が提供する模擬問題集です。模擬問題が合計で300問準備されており、すべて無料で利用できます。

内容はちょっと難しめです。実際の試験が一問につき2〜3個の知識を問うのに対して、RExは3〜5個ほどの知識が問われる感覚です。

勉強の流れ

  1. 初日に模擬を受けてみて自分の現在地を知る
  2. 一週間で教本を読み切る
  3. 残り一週間で模擬を繰り返し「解く→復習」のサイクルを回す

こんな流れで取り組んでました。 模擬試験〜本番の点数推移としては以下の通りでした。

  • 1回目 28点
  • 2回目 36点
  • 3回目 48点
  • 4回目 52点
  • 5回目 74点
  • 6回目 86点
  • 本番 94点

試験前日の6回目まで合格点を超えずめちゃくちゃ焦ってました。 Rubyをしっかり学んだのが数年前だったので教本を一回読むだけでは脳に定着しませんでしたね。前半の教本を読む週は全く無駄では無いにせよ、もうちょっとやりようはあったかなと思います。

後半に入っても模擬の点数が上がらず復習範囲が膨大だったので後半一週間は思ったように回せませんでした。5〜6回目あたりでテストの形式に慣れたのと、知識が定着してきてグッと点数があがりました。

試験対策

学習方法とは別の試験対策としては直前3日はきちんと寝ることを心がけました。平日は通常5〜6時間の睡眠時間なことが多いのですが、それではベストパフォーマンスにならないことは承知していたので、7〜8時間寝てベストパフォーマンスにもっていきました。 模擬の点数が上がらない中で悩みましたが、この期間だけは平日の間は通勤の間だけ勉強して、家ではさっさと寝るようにしました。

あとは、自分でも意識してなかったですが日曜日に試験を設定したのも良かったです。土曜日にやれるだけをやって、日曜日は試験の直前にぱらぱらノートを見るくらいで済ませることができました。前日にやれるだけやっておくと当日が楽ですね。

参考になったブログ

最後に

引き続き学習を続けてRuby Goldもいつかとれるといいなーと思います。 これからRuby Silverを受けられる方、応援しています!

サイクリングの事故やトラブルがあった地点の情報を集約し見える化するサービス「MAAKS(マークス)」をリリースしました。【Rails + Fly.io + MapBox】

MAAKS(マークス)ロゴ画像

はじめに

サイクリング中の事故低減を目的に、サイクリングの事故やトラブルがあった地点を見える化し集約するサービス「MAAKS(マークス)」をリリースしました。

この記事では Web アプリの概要や使い方、技術スタックやこだわった点、また開発過程での苦労や学んだこと、さらには今後の展望まで、詳しく解説します。

サービスURL

https://maaks.jp/

リポジトリ

https://github.com/YukiWatanabe824/MAAKS

自己紹介

こんにちは、渡邊有喜(わたなべ ゆうき)と申します。

自転車メーカーに勤める傍ら、プログラミングスクール「フィヨルドブートキャンプ」でプログラミングを学び、今回紹介するサービスを開発しました。

記事を書いている段階では卒業目前、卒業後はWEBエンジニアを目指しています。

サービスの紹介

サービスの紹介に入る前になんでこのようなサービスを作ったか、について話したいと思います。

サイクリングは楽しい、でも…

私は現在自転車メーカーに勤めています。大学の頃は自転車サークルに所属していて、全国津々浦々を自転車で旅するような活動をしてました。加えて学生の頃のアルバイトは自転車店…と自転車の魅力に取り憑かれて、人生が変わった人間の一人です。サイクリング好きが高じてメーカーに就職をしたわけですが、どこへ行っても自転車に関して変わらない事実がありました。それはサイクリングは事故リスクの高いアクティビティということです。

サイクリングをするようなスポーツ自転車はスピードも出ますし、二輪の特性上、転倒のリスクがどうしてもあります。ソースが見つかりませんでしたが、サイクリングはケガのリスクが高いアクティビティだという結果が出た調査があったことも記憶しています。 私自身は大きな事故の経験はありませんが、周囲では救急搬送を伴う事故がたびたび起こっていたり、同じくサイクリング好きが高じて入社したはずの部下が自転車事故の後遺症が原因で退職するのを見送ったこともありました。

また、2022年、2023年とロードレース中の死亡事故もありました。特に2023年のツールド北海道の死亡事故は大々的に報道されましたから記憶に残っている方もおられるかもしれません。

私自身、サイクリングと出会ってなければ今の人生はありません。サイクリングのおかげで今があると言えます。そんな大事なサイクリングが不幸な人を生み出す現状を変えられないか、とプログラミング学習をしながら考えるようになりました。

とはいえ、現職で取り組もうとするとROIありきとなってこのような活動はなかなかできません。そこでフィヨルドブートキャンプの卒業制作に、このテーマを組み込んで「サイクリングで不幸になる人をゼロにする」取り組みの小さな一歩を始めました。

その結果できあがったのが「MAAKS」です。

コミュニティを超えて知見を共有する

MAAKSの根底にあるのはWEBエンジニアの「知見を共有」する精神です。

サイクリングには統一した情報網がありません。一方でWEBエンジニアにはQiitaであったりZennであったり様々なプラットフォームが存在しています。

サイクリングルートにおける知見(難易度や危険スポットの情報)についても、車体を購入した自転車店であったり、サイクリングコミュニティ、友人知人、はたまたライドイベント主催者など数多くのローカルコミュニティが独自に情報を持ち、ローカルコミュニティ内でのみ展開されてきました。

つまり、サイクリスト界隈にはコミュニティが独自に持つ知見がコミュニティを超えて共有される環境がありませんでした。

そこでMAAKSは事故などのリスクが有る地点に限定して共有するプラットフォームとして情報共有を通じてサイクリング時の事故リスク低減を目指しています。

使い方

サービストップページ

危険スポットをみる

危険スポットを見る マップ上に表示された水色のマーカーはその地点でなんらかのトラブルに見舞われた人の投稿があったことを示します。 水色のマーカーをタップ or クリックすることで、投稿された内容を確認できます。

アカウントを作る

アカウント登録画面 このサービスではサービス内で独自のアカウントを取得するか、Googleアカウントを使用することでログインすることができます。 ログインすると危険スポットを登録することができるようになります。

危険スポットを登録する

危険スポットの登録 マップ上をタップ or クリックすると赤いマーカーが表示されます。 赤いマーカーを長押し or 右クリックして「スポットを作成する」を選択すると、サイドメニューに危険スポットの登録メニューが表示されます。 必須事項を記入し、「登録する」を選択するとデータが保存され、スポットが登録されます。

危険スポットを削除する

危険スポットの削除 自身が登録した危険スポットは削除することができます。

アカウントを削除する

アカウントの削除 「マイページ」→「プロフィール編集」でアカウントの削除を選択することができます。 アカウントを削除するとこれまで作成してきたスポットも削除されます。

技術スタック

開発

ペーパープロトタイプ

制作するサービスのコンセプトが決まった後にペーパープロトタイプを作成しました。

マップ上に地点を表示するサービスはすでに先行して大量に存在します。ユーザーの利便性を考えて先行するそれらのサービスにある程度似せた画面構成と操作性を採用することで、私のサービスを使用する際においてもユーザーが操作方法を覚える負荷を低減させることを目指しました。ここでターゲットマークにしたのが「Google map」と「大島てる」の2つです。この2つのサービスはかなり使い込んで画面構成を検討しました。

ペーパープロトタイプ

この段階で技術的な骨子の部分は「マップを表示して、ユーザーが登録した地点を表示する」とかなりシンプルになるだろうと想定していました。

技術選定

技術選定におけるテーマとして以下の3点がありました。

  • 時間短縮を目指すこと
  • フロントエンド/バックエンドはRailsが提供する一貫した環境を利用すること
  • 外部サービスと連携すること

1つ目は時間短縮です。現職で平日日中に働きながらの制作+プライベートでは結婚式や家探しなどを同時並行していたので専念できる方に比べて時間がありませんでした。

そのためチャレンジングな技術スタックはあえて控えめとし「形にすること」を第一優先しました。とはいえ、Rails 7とHotWireもカリキュラム外ではありましたので、このあたりは0から学びました。

2つ目はフロントエンド/バックエンドにRailsが提供する環境を利用することです。

Railsをバックエンドに使用することはFJORDBOOTCAMPのカリキュラムで学んだことを活かしたかったので既定路線でした。

一方でフロントエンドはカリキュラムで学んだVueと使うか、トレンドのReactを使うか、はたまた直近のFJORDBOOTCAMP卒業生が多く採用していたHotwireを採用するか悩みました。 最終的にHotwireの「バックエンドで処理をおこないHTMLを返すことで動的なクライアント画面を実現する」アプローチはフロントエンドの責任が重くなりすぎた現状を変えることが目的、というRails開発者DHHのメッセージを読み、とても共感と好感に思ったことからHotWireをフロントエンドに選択しました。

3つ目は外部サービスとの連携です。サービスコンセプトが先にありましたのでマップをどうするか、という課題から自然と外部サービスを活用する方向性ではありました。とはいえ、普段自分が使っているサービスでもGoogleアカウントでのログインのような外部サービス連携はよくあるのでユーザーの利便性向上のため、実用に足るサービスにするためチャレンジすることにしました。

開発中に感じたこと

わからないことが多い

自分一人でサービスをローンチする経験はもちろんのことなかったので、サービス開発はわからないことだらけでした。

暗中模索というのがぴったりで、ふわふわとした完成形だけが頭の中にイメージとしてあるけれどそれを実現する方法はわからない。常に手探りの開発でした。

現職で全く未知の業務に数ヶ月単位で取り組んで完成させた経験があったのでストレス的な部分はそれほどでもありませんでした。未知の分野へのストレス耐性に関してはフィヨルドブートキャンプでの学習のおかげもあったかもしれません。

とはいえ未知なことが多すぎて処理の妥当性に判断がつかないことが振り返ってみてよくありました。調査し尽くしたはずだけれども、確証がないので結論が出せない状態になってしまう感じです。そういったときはスクール内で質問をするなどして立てた仮説を結論にしていきました。

カンバンをこまめに管理した

わからない部分が多いので可能な限りカンバンにタスクを書き出して管理していきました。 カンバンはGitHubProjectを使い、簡易的なスクラム形式で取り組んでいました。GitHubProjectを使ったスクラムフィヨルドブートキャンプのチーム開発プラクティスで培ったノウハウでした。自作サービスでも週一の進捗報告会があってリズムを作れるようにスクール側で用意してくれているのは助かりました。

カンバンを細かく管理することで細かいながらも進捗が視覚化され、メンタルの安定にも繋がりました。また、分からない部分が多い話とも関連して、自分がなぜこのタスクに取り組んでいるのかがわからなくならないようにしてくれるのもメリットでした。

サービスの持続性を高めるために低コストに

フィヨルドブートキャンプ内でも案内がありますが、サービスに固定費が発生する場合は比較的短命に終わり、クロージングしてしまうという話があったので、MAAKSでは可能な範囲で低コストを心がけました。

例えば地図に関わるAPIに関しては王道といえるのは「Google Maps」でしたが、MAAKSでは後発の「MapBox」を採用しました。コスト面ではGoogle Mapsが28500回の呼び出しまで無料に対し、MapBoxは50000回まで無料だったので圧倒的にMapBoxのほうがコスト負担が軽く、サービスの寿命を伸ばしてくれるだろうと判断しました。

こういった技術選定をできることも自作サービス開発の醍醐味だと思います。コストを取るか、ドキュメントや周辺情報などの充実度を取るか、ビジネスにおいても悩ましいポイントじゃないでしょうか。経験できてよかったです。

UI/UXはローカルアプリケーションを参考に画面遷移を極力なくした

UI/UXでこだわったと明確に言えるのはモーダルを多用した部分です。スクール受講生が送り出すサービスの多くが「サービスの説明/紹介ページ」→「サービスページ」という順番で作られています。これが非常に煩わしく感じていました。

というのも私自身の生活においてWEBサービスをそこまで使っていません。多くがスマホで操作するローカルアプリでした。そしてビジネスにおいても多くの事業会社がそれぞれアプリを送り出している時代です。操作性のスタンダードはローカルアプリにあり、と考えてローカルアプリを参考にした画面づくりに取り組みました。

そこで形になったのがモーダルを使用してサービスページに説明や紹介のコンテンツを埋め込む方法です。これによってサービスのメイン部分を使用する限りにおいては画面遷移なく使い続けられることができます。

PC用の挙動とスマホ用の挙動を作って最適化した

スマホタブレット、PCでの使用を考慮してレスポンシブデザインを導入しています。

開発中の苦労したポイント

マップ⇔サービスでデータをやり取りする

「マップを表示して、ユーザーが登録した地点を表示する」機能を実装するために、MapBoxのAPIを叩いて出力される座標データを取得して、MAAKS側でユーザーが入力した事項とセットでDBに保存、必要に応じて保存したデータをMAP上に出力できるようにする必要がありました。

マップの座標を読み込んでマーカーを立てる処理やDBからスポットの情報を取得して座標にマーカーを出力する

この実装をするには

  • MapBoxのAPIから必要なデータを取得すること
  • フロントエンド(HotWire Stimulus)でMapBoxAPIから取得したデータ、サービス側から取得したデータを扱う処理を構築すること
  • Railsでフロントから渡されたデータを適宜処理すること、反対にフロントに適宜データを渡すこと

と、これまで学んできたこと+このサービスで開発する上で学んだことを組み合わせることで構築しました。応用編といった感じです。

例えばMAAKSでは、マップ上をクリックすると現在地を表す赤いマーカーを表示します。その赤いマーカーを操作することで危険スポットの登録画面を表示することができます。

// MAP上に赤いマーカーを表示するメソッド
createNewSpotMarker() {
    this.mapTarget.mapbox.on("click", (e) => {
      if (this.mapTarget.newMarker) {
        this.mapTarget.newMarker.remove();
      }
      this.mapTarget.newMarker = new mapboxgl.Marker({
        draggable: false,
        color: "#cf5d40",
      });

      const el = this.mapTarget.newMarker.getElement();
      el.id = "new_spot_marker";
      el.setAttribute("data-controller", "spot new-spot-marker");
      el.setAttribute("data-spot-target", "spot");
      el.setAttribute("data-action", "contextmenu->spot#showSpotMenu");

      this.mapTarget.newMarker.setLngLat([e.lngLat.lng, e.lngLat.lat]).addTo(this.mapTarget.mapbox);
    });
  }

this.mapTarget.mapbox.on("click", (e) => {}) はMapBoxのAPIです。クリックした地点の情報を取得します。

そこからStimulus(JavaScript)を用いてMAP上にマーカーを出力。マーカーに対するイベントや座標情報をデータ属性として付与させることでその後の危険スポット登録画面の呼び出しや、データをDBに保存する場面にデータを受け渡しています。

MapBoxAPIを安全に利用する

MapBoxのマップを安全に利用しようとするところには盛大につまづきました。

MapBoxのマップはMapBox上のアカウントに紐づいたアクセストークンを読み込ませることで地図を画面上に表示できるようになります。

マップはCDNのようにフロント側で外部から読み込んで表示されており、アクセストークンをフロント側に渡す必要があります。このときに「アクセストークンはフロントに渡していい情報なのか、サービス利用者から見える形になって問題ないのか」という部分の判断がつかず、結論さえ分かれば非常に簡単な話ではありますが苦戦しました。

判断するためには一般的な話として外部APIを使う上で使われる手法を確認する必要と、MapBoxではどのようにしているか、を確認する必要がありました。ドキュメントやMapBoxのDiscordコミュニティを調べた結果、MapBoxのサービス側で読み込み元のURLを制限できることがわかりました。このやり方で妥当かどうかをフィヨルドブートキャンプの質問タイムで確認してようやく判断がつきました。

現在ではサービス側でURLを制限した上でcredentialsとして環境変数のようなかたちでアクセストークンなどは読み込むようにしています。

外部ストレージサービスを導入する

MAAKSではユーザーごとに画像をアップロードしてアイコンを設定することができます。

当初はFly.ioのVM(=バーチャルマシン)のローカル(volumes)にファイルを保存する形を検討しておりましたが、AmazonS3を導入することに切り替えました。

Fly.ioのVMは2台体制で稼働しており、保存されるファイルはそのどちらかに格納されます。また、ファイルを読み込む際には2台のVMのどちらか1台のみを読み込むため、ファイルが存在しない方のVMを読むこむとファイルは表示されません。

Fly.ioのドキュメントや掲示板を読み込み対応を検討した末、フィヨルドブートキャンプで先行してFly.ioを使用していた方を参考にしつつ、Railsが推奨する「本番では外部ストレージサービスを使う」ことに従い、AmazonS3を導入てファイルを保存する方法を採りました。

「本番では外部ストレージサービスを使う」ことはRails Guideにはさらっと書かれていたのみ&本番の運用経験がなかったことから予想外の対応になりました。

開発してよかった部分

躓いたところは記録に残す

カンバンの管理と同様の話になりますが苦戦した部分はNotionやフィヨルドブートキャンプ内の日報などに記録をこまめに残しておきました。この記事もそれらを片手に「こんなことがあったな」と思い出しながら書いています。

苦戦した箇所リストは今後ブログのネタ帳として再利用される予定です。

開発に取り組むことで技術にさらに興味が湧いた

開発に取り組んできたことでRails(特にHotWire)にさらに興味が湧いて勉強会(HotWire.love)にも参加しました。

仕事としてプログラミングに取り組んだ際に、私はどのように技術と向き合うんだろうと思うことがありましたが自然と好奇心が湧いてコミュニティに参加するアクションを取れました。エンジニアとして生きる上では学習が欠かせないことは既知の事実でしたので、将来に対する不安が若干減ったように思います。

調べる先が広がり、海外の媒体に対するハードルが下がった

開発に取り組んでいて不明点が出てきたときの対応の幅が広がりました。

自作サービス開発以前は日本語媒体やコミュニティ、英語圏であってもせいぜい公式ドキュメントに調べる先が限定されていましたが、自作サービスを作る過程の中でどうしてもこれらでは情報を得られないことがたびたび発生したのでそういったときには英語圏の媒体、stackoverflowや公式のコミュニティ、時には中国語圏の媒体まで調べる先を広げました。

翻訳機能を使ってなんとかしてる状態ではありますが、調べることに関しては海外の媒体を活用することのハードルは下がりました。

これから

機能を追加したい

一旦完成は迎えましたが、やりたいことはまだまだあります。

  • 危険スポットの画像を投稿できるようにしたい →事故時のケガの画像が投稿されるんじゃないかと思って保留中
  • マップ上のスポットをクラスター表示させたい →投稿の多いエリアはトラブルをもたらす何かがあると推測できる
  • サイクリングのルート生成機能 →MapBoxのAPIとしてあるようです。リリース後の集客次第…。
  • コミュニティ機能 →サイクリングコミュニティを形成する拠点としてこのサービスを成長させたい

などなど。

まずは多くの人に使われるサービスになることを目指して、パフォーマンスやUI/UX、利便性の向上に取り組みたいと思います。

いずれはサイクリストの誰もが使ってくれるサービスになることを目指します!

おわりに

自分の思い描いたサービスが自分の手で形になって開発環境で動いたとき、デプロイして世の中とサービスが繋がったとき、本当に嬉しくなりました。大変なことも、苦しいこともありましたが、自分がスキルアップし前に進む感触を得られる日々は楽しいものでした。

サービスの構想を練り始めたころから考えると、リリースまで半年ぐらいかかってしまいました。それでも諦めず、粘り強くこのサービスを完成させたいと気持ちが続いたことは多くの方に支えていただいたからです。

今後もこの経験を糧にして、スキルアップしていきたいと思います。

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

謝辞

企画・開発・レビューまで面倒を見ていただいたmachidaさん、komagataさん、フィヨルドブートキャンプのメンターの皆さん、 切磋琢磨したフィヨルドブートキャンプの受講生の皆さん、 このサービスの案出しに付き合ってくれた友人のS、

そして、この取り組みを理解し支えてくれた家族に感謝します。

ありがとうございました。

2024年の目標

こんにちは、Watanabeです。

毎年恒例の今年の目標記事です。

  1. エンジニアに転職する
  2. 職業エンジニアとして軌道に乗る
  3. 円満な家庭を築く
  4. 書籍を最低20冊読む
  5. ブログ記事を120回投稿する

エンジニアに転職する

昨年の12月にようやくフィヨルドブートキャンプを卒業することができまして、現在就職活動にむけて準備を進めています。

なのでまずはエンジニアになることが第一目標ですね。頑張ります。

職業エンジニアとして軌道に乗る

エンジニアになったあとのことですが、未経験で別業界に行くのでそれはそれは大変だと思うんですよね。

特に現職がかなりアナログなのでギャップを感じる場面は数え切れないくらいにあると予想します。

そういう中でいち早く慣れて、職業エンジニアとして仕事に取り組んでいくことが目標です。

円満な家庭を築く

家庭のサポートあってのフィヨルドブートキャンプでの学習だったし、転職活動ですね。

転職が決まったら奥さんにはこれまでのお礼としてなんらかお返ししたいところ。

書籍を最低20冊読む

いっとき、年間60冊くらい読んでたことがあって、知識として結構あとまで役立つことが多かったので継続的に読書は取り組んでいきたいですね。

未だに電子書籍がいいのか、古本を安く買うのがいいのか迷うんですよね。 毎回定価で本買ってると費用が馬鹿にならないです(´;ω;`) 技術書購入補助がある会社が羨ましいです。

ブログ記事を120回投稿する

これまでフィヨルドブートキャンプの日報を書いてきていたのでこれをブログに移行して、技術的な発信はどんどんやっていきたいですね。 仕組み化とか習慣化しないと120回はなかなかできないと思うので工夫しながら取り組んでいきます💪

2023年のまとめ

そろそろ今年を振り返らないと、なにも書くこともなく2023年は過ぎ去ってしまう危機感の元、2023年12月30日の夜中にこの記事を書いています。

さて、年始めに↓の記事で今年の目標を設定しています。 yukiwatanabe.hatenablog.com

それに触れつつ今年を振り返ってみようかと思います。

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

12月にフィヨルドブートキャンプが卒業ステータスになりました。 年始の目標では5月末までと設定していたので大幅に超過していますが、なんとか一区切りをつけることができました。

悩ましいのは超過した分のしわ寄せが今きていて、今後の選択を迫られているところです。 目標通り5月に卒業できていればこうはなってなかったのに…。と思いつつも振り返ってみて5月に卒業できたかと言われれば「絶対無理」としか言いようが無かったですが。

入籍して結婚式して家を買った

2月に入籍して7月に結婚式をあげて10月に家を買いました。 2023年はプライベートが本当に目まぐるしかったですね。

結婚式は妻がすごい頑張ってくれていたのでそれに甘えるばかりだったのですが、それでも打ち合わせをそれなりにやりましたし、苦手な交渉事にもTRYしました。

式後に家を買おうと動き始めた8月下旬から12月上旬の引っ越しまではもう毎週そのために動いていたので疲弊しきってました。

仕事とプログラミング学習とプライベートに人生の一大行事をぶつけていくもんじゃないな、とこの三重生活の終わりが見えてきて思います。

妻にも負担をかけていたので「並行作業が苦手だね」とたびたび言われる始末…。 たらればですがプログラミング学習の時期がもう一年早ければ、去年の12月には色々落ち着いていたのでどれだけ都合が良かったか、と思います。

数年越しのProjectが始動

職場での話になりますが、前任から会社に働きかけていたProjectが承認されて始動したのが今年でした。

スタートのために閑散期を使って事前調査を職場的には異例なくらいおこなってメリットを算出したり、相見積もり業者を使って商談を重ねて費用交渉に取り組んだりしました。

ここから三段仕掛けくらいしてあってうまく投資が継続してProjectの第二弾、第三弾まで進んでもらえれば、一気に販売、マーケティング、アフターサービスの取り組み方に幅をもたせられるようになるので楽しみな限りです。

バスに轢かれた

1月の出来事ですが、交差点で私を見落としたバスに轢かれたのも2023年でした。

信号待ちで止まっていたバスが信号切り替わり後に曲がろうとして私を跳ね飛ばしていきました。不幸中の幸いで極低速ではねられふっとばされたので、轢かれたり引きずられることもなく、打撲と身につけてたものがいくつか破損するだけですみました。

とはいえ、事故対応は10月ごろまでかかったのでこれも結構手間でしたね。 (保険屋と結構やり合いました)

プログラミング関係

チーム開発

4月から7月ごろまでの3ヶ月間、フィヨルドブートキャンプの名物プラクティス「チーム開発」に取り組みました。

チーム開発は実際の業務に近い環境でフィヨルドブートキャンプで使用しているアプリを修正していくプラクティスです。 GitHubを使ってやり取りをして受講生間でレビューなどもします。

自作サービス開発

7月頃から現在に至るまで自作サービス開発に取り組んでいます。もうほぼほぼ完成しているのですが、ものづくりによくある話で「0〜80%と80%〜100%は同じ時間と手間がかかる」という状態でレビューの対応を進めている状態です。

発表は近々やります。お楽しみに。

終わり

2023年は過去一いそがしい年でした。

年齢のせいもあるのか一年が本当に早かったです。 (最近、通勤時間が伸びたのですが本を読んでいるとあっという間に過ぎてしまうのでまじで年齢の部分がありそう)

来年はターニングポイントになる年にしたいですね。がんばります。