スタメンのCTOの @tnir です。前回は 9年選手のTUNAG RailsアプリをRuby 3.4にアップデートした という記事を書きました。スタメンでは、従業員体験プラットフォーム「TUNAG」の開発にGitHub Copilotを導入し、特にCopilot WorkspaceとGitHub Copilot pull request summaries・GitHub Copilot code review(旧Copilot for Pull Request)を活用しています。 注)Copilot Workspaceは執筆時点(2025年2月)でpublic previewです。 先週末にOpenAI o3-miniがGitHub Copilot上でも利用可能になり利用を開始し1週間ほど経過したので、この記事では10年選手のモノリスアプリケーションを継続的に改善していく上で、GitHub Copilotがどのように役立っているかをご紹介します。previewである機能の利用は GitHub Pre-release License Terms - GitHub Docs に基づきます。 github.blog モノリスの課題と継続的改善 TUNAGは、10年以上の歴史を持つモノリスアプリケーションです。長年にわたって機能追加や改修を重ねてきた結果、コードベースが複雑化し、以下のような課題を抱えていました。 コードの可読性・保守性の低下 新機能開発・改修コストの増大 技術的負債の蓄積 これらの課題を解決し、TUNAGの成長を支えるためには、継続的な改善が不可欠です。 GitHub Copilotの導入 開発効率向上のため、2022年ごろよりGitHub Copilotを導入しました。当時のエンジニアからはこのような評価を得ており、その後現在に至るまでエンジニアには有償版Copilotアカウントを付与しています。 2022年時点での社内エンジニアの評価 先週末の以下のGitHub CopilotのOpenAI o3-mini (preview)サポートの発表を踏まえ、今回は、特にCopilot WorkspaceとGitHub Copilot pull request summaries・GitHub Copilot code review(旧Copilot for Pull Request)に注目し、モノリス改善への効果を期待しました。 GitHub Models users with a paid Copilot plan will also be able to leverage the o3-mini model to enhance their AI applications and projects later today. In the GitHub Models playground, you can explore o3-mini’s versatility as you experiment with sample prompts, refine your ideas, and iterate as you build. You can also try it alongside other models available on GitHub Models including models from Cohere, DeepSeek, Meta, and Mistral. OpenAI o3-mini now available in GitHub Copilot and GitHub Models (Public Preview) - GitHub Changelog Copilot Workspaceの活用 Copilot Workspaceは、IDE上でコードの補完や提案を行ってくれるため、開発効率を大幅に向上させることができます。筆者はVisual Studio Codeを利用していますが、そのエクステンション vscode:extension/GitHub.copilot?referrer=docs-copilot-ai-powered-suggestions を利用しています。 code.visualstudio.com Copilot Chat Copilot Edits TUNAGの開発では、Copilot Workspaceを活用することで、以下のような効果が得られています。 エラーハンドリングの抜け漏れの回避 類似コードの提案によるコーディング時間の短縮 API仕様の自動生成による開発効率化 特に、初期実装から時間が経過したコンポーネントにおいては、Copilot Workspaceがコードの理解を助け、開発スピードを向上させる上で非常に役立っています。 Copilot for Pull Request (GitHub Copilot pull request summaries・GitHub Copilot code review)の活用 Copilot for Pull Requestは、プルリクエストのレビューを支援してくれる機能です。2023年3月時点では GitHub NextでCopilot Enterpriseユーザーのみに提供されていた ため、利用を断念していた人・組織が多いのではないかと思います。GitHub Web上で利用しています。( Copilot for Pull Requestは2023年12月 に廃止されました) 現在は Copilot for pull requests という形で独立したドキュメントになっており、GitHub Copilot pull request summariesとGitHub Copilot code reviewが主な機能です。 TUNAGの開発では、 Copilot pull request summariesとCopilot code reviewを活用することで、以下のような効果が得られています。 変更箇所の説明文の自動生成 レビュー観点の提案 コード品質の向上 プルリクエストのレビューは、コード品質を維持する上で重要なプロセスですが、多くの時間と労力を必要します。Copilot for Pull Requestは、レビュープロセスを効率化し、より質の高いレビューを実現する上で貢献しています。 モノリス改善への貢献 GitHub Copilotの導入により、TUNAGの開発Developer Experience (DevEx) チームは、モノリスアプリケーションの継続的な改善を効率的に進めることができるようになりました。 コードの可読性・保守性の向上 新機能開発・改修コストの削減 技術的負債の解消 2025年に入ってから、DevExチームではバンドリングツールをwebpack 4/5からesbuildへのリプレースするプロジェクトを推進していたのですが、そちらでも活用ができています。 コミットメッセージも次のようになっていて、Copilotというエンジニアと開発している感覚にもなりました。 Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> 新モデルの利用 先に書いた通り、1/31にo3-miniがリリースされると同時に、GitHub Copilotでも利用が可能になりました。特に GitHubを運営するMicrosoftグループとOpenAIの協力なパートナーシップ の元、高速なo3-mini対応が実現したと認識しています。これはシングルプロダクト・all-in-oneプロダクトの強みを最大限活かしたものであり、TUNAGが同様にシングルプロダクト・all-in-oneプロダクトであることのSaaS事業運営上の強みと通じるものがあると感じることができました。 blogs.microsoft.com o3-miniだけではなく、既にGemini for Google WorkspaceやGoogle AI Studioで活用できていた Gemini 2.0 も利用可能にしています(オプトインが必要でした)。 今後の展望 私たちは、以下の施策を通じてさらなる改善を目指しています。 本日発表された agent mode を活用した開発の深掘り 既に手元では利用できていましたが、公式に使えるようになったということもあり、深掘りして利用できればと思います。 テスト自動化の拡充 テストケースの自動生成を通じたテストカバレッジの向上ができそうだと感じています。 リグレッションテスト強化にも使えそうです。 ドキュメンテーションが不足しているケースがあるので、その解消にも役立ちそうです。 コードベースの自動ドキュメント生成 ADRの整備にも一役買いそうです。 Gemini 2.0の統合 これまではGeminiとGitHub Copilotでいったりきたりが必要でしたが、それらが統合されたことにより、IDEまたはWebブラウザで操作できるのは快適でした。同じ画面上で用途に応じて使い分けをしていこうと思います。 github.blog まとめ GitHub Copilot、特にCopilot WorkspaceとCopilot for Pull Requestは、モノリスアプリケーションの継続的改善を支援する強力なツールです。DevEx・プラットフォームエンジニアリングの領域においては、まだ適用できないケースもありましたが、それでも生産性向上への貢献は絶大だと感じました。 スタメンでは、GitHub Copilot以外のGenerative AI技術・プロダクトを活用を進めているため、そちらについても別途共有できればと思います。GitHub Copilotの導入は、複雑なアプリケーションを抱える開発チームにとっても非常に有効な手段なので、未導入で迷っているようでしたらぜひ試してもらえればと思います。 注)本記事の内容の執筆に関して、GitHub Copilot の利用規約 (GitHub Copilot プライバシーに関する声明など) を遵守しています。Copilot Workspaceを含む一部の製品機能においてプレビュー版が含まれているため、将来の仕様変更やサービス提供終了に注意が必要です。 この領域でアクセルを踏むため、以下のポジションでエンジニアを募集していますので、チェックいただけると幸いです。 herp.careers herp.careers herp.careers herp.careers 参考 Responsible use of GitHub Copilot pull request summaries - GitHub Docs Using GitHub Copilot code review - GitHub Docs
TUNAG with Ruby 3.4 昨年末12月25日にRubyの最新バージョン3.4がリリースされました。従業員体験プラットフォームTUNAG(ツナグ)を開発・運用している私たちのチームでは、この最新バージョンにいち早く追従。複数のRuby on Railsアプリケーションのバージョンを、すべて3.4.1にアップデートしました(2025年1月10日現在)。アップデート後1週間ほど問題なく運用できていますので、速報として記事化します。 移行前はRuby 3.3.6+YJIT、移行後はRuby 3.4.1+YJITとなります。 $ ruby -V ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +YJIT +PRISM [x86_64-linux] 過去のTUNAGにおいてRuby/Railsのアップデート実績については以下の記事もご覧ください。 tech.stmn.co.jp tech.stmn.co.jp tech.stmn.co.jp YJIT 3.4 今回はYJIT 3.3からYJIT 3.4への移行最終局面でMaxime Chevalier-Boisvertさんによる記事 https://railsatscale.com/2025-01-10-yjit-3-4-even-faster-and-more-memory-efficient/ が公開されたので、最終チェックとして、この情報を活用しました。 特に今回のアプリケーションでRubyの影響を受けるのはActiveRecordの箇所だと捉えると、その高速化は+2.6%と推測していました。 railsatscale.com --yjit-mem-sizeの調整 Ruby 3.1から提供されてきた --yjit-exec-mem-size オプションに加え、YJIT 3.4では --yjit-mem-size オプションが2024年10月に新たに導入されています( https://github.com/ruby/ruby/pull/11810 )。 --yjit-exec-mem-size オプションはこれまでRuby 3.3においてもデフォルト48 MiBのままで運用していたため、 --yjit-mem-size=128 (in MiB) で運用を開始し目立った問題は発生していません。 github.com 全体のメモリ消費量 メモリ使用量については過去のRuby 3.1-3.3周辺のアップデートの中でやや苦労した Ruby/YJITエコシステム的にもメモリの問題はある程度落ち着いてきており、チーム組織内でも特に新たな発見はなく、スムーズにリリースに至りました。 実際のパフォーマンス差 実際に移行前後でのRailsアプリ (puma サーバで実行)のレイテンシー差異は軽微で、有意な差がある高速化は全体平均値や主要な個別箇所では確認できませんでした。今回はcanaryリリースをしない選択をしており、production環境において同一ソースコードの実行結果の差を取得していません。 native gem システム内部通信にgRPCを使っていることもあり、native gemに依存している状況です。Rubyマイナーバージョンアップ時はnative gemの最新マイナーバージョンへの追従が例年遅れる傾向にあります。 Ruby 3.3リリース直後と同様に、Ruby 3.4リリース直後もこれらのgemではネイティブビルドが利用できなくなりました。DevExはやや低下しますが、最新技術の活用を優先しています。この制約は約1ヶ月程度で解消される見込みで、通常は毎年2月ごろに改善されています。 native gemはfat gemと呼ばれることもあり、廃止したいという意見もあるようです。が、RubyGemsのキャッシュの兼ね合いからnative build gemは開発・運用業務をする上ではまだ必須かなという認識です。 www.clear-code.com 特に grpc gem はローメモリでのビルドが難しくCI環境などでメモリ不足が起因でビルドに失敗するケースに遭遇しています。こちらの問題はRuby 3.4対応のgrpc native gem (grpc 1.70.0予定) で解消される見込みです。 Stacktraceにクラス名が含まれることでSentryでFingerprintが変わる 2024年2月に、stacktraceにメソッド名のみが含まれていたものがクラス名+メソッド名が出力されるようになりました。 github.com Ruby 3.3以前に「後回しにした」(*1)エラーが、再度新規エラーとして扱われるようになりました。幸い、該当するエラーは数件程度だったため、手動でグルーピングすることで問題なく対応することができました。 事前準備は大事 プレリリース版より検証することが重要です。今回のRuby 3.4シリーズのプレリリースのうちpreview2とrc1を利用して、2024年中より評価・検証を進めました。 Ruby 3.4.0-rc1 2024-12-12 Ruby 3.4.0-preview2 2024-10-07 オフラインで開催されるRuby/Rails勉強会も有用な情報として助かりました。特にFukuoka.rb / 株式会社Ruby開発共催の福岡 Rubyist会議 04への参加は内部構造を理解するのにとても参考になりました。 regional.rubykaigi.org 毎週のように都内ではRuby関連勉強会は実施されているので、タイミングが合えば今後も積極的に参加していこうと思います。また、年次カンファレンスRubyKaigiも最もRubyについて深い議論ができるため、参加したいと考えています。 今年もスタメンからRubyエンジニアを中心にプロダクトメンバー複数名で参加する予定です。 いつやるのかという意思決定 プロジェクト実施を意思決定する以前から利用していたRuby 3.3は、2027年3月にEOLを迎えることが確定していました。そのため、今回のバージョンアップはそれまでの約2年間で実施する必要がありました。組織・プロダクトの状況を考慮すると、最大2年間は後回しにすることも可能でしたが、2024年のコミュニティへのフィードバックという貢献を最大化するため、このタイミングでの実施に至りました(実際には12月末はホリデーシーズンでチームは稼働していなかったため、年明けからの開始となりました)。 2025年第1週には最終プロセスに入り、すべて完了しています。しかし、productionレベルでの投資は2024年10月頃から緩やかに開始していました。例年以上に、特に今年の1月はチームに多くの新入社員が参画したこともあり、最初の週の実施はハードスケジュールでした。個人的には、2週目の実施でもよかったのではないかと感じています。 早期に実施することにリスクを感じる方もいるかと思いますが、私たちのチームではプロダクト内でのリスク回避策を講じることで、リスクを限定的に抑えられています。このあたりについては、読者の皆様が技術選定をどのように行っているのか、今後お伝えできればと思っていますし、他社の事例についても情報交換したいと考えています(執筆時点では、一定規模以上でRuby 3.4にアップデートしたという報告事例はあまり見つけられませんでした)。 我々もRuby 3.4力をつけて4月に愛媛で開催されるRubyKaigi 2025に参加し、各社でのRuby 3.4利用状況について議論できることを楽しみにしています。 参考 noteにも詳細を載せた関連記事を掲載していますので、ご参照ください。 https://note.com/takuya_stmn/n/n673ed32f80fe?magazine_key=m3805182520ce
TUANGのプロダクト開発チームでAndroidアプリを開発している カーキ です。 最近は、ダンダダン のアニメ放送に毎週歓喜しています。 2024年の末に投稿しようと思っていたものの、気付いたら年を越して2025年になっていました。 スタメンのAndroidエンジニアは3-4人と、決して大きい組織ではありませんが、機能開発をしつつプラットフォームの改善にも並列で取り組んでいます。 今回のブログでは、2024年の1年間でのAndroidチームでの技術的な変化・挑戦をまとめて紹介します。 Compose のコード規約を作成 TUNAG の Android プロジェクトでは、2021年ごろから Jetpack Compose をUI作成のフレームワークとして導入していました。 これまでは Jetpack Compose について知見にあるメンバーが知見の浅いメンバーに対して教えたり、レビューを通じて知見を共有することで、Jetpack Compose の共通認識を作っていました。 ただ実際にComposeのコードを書くメンバーが増えたときに、複数の書き方があるときにどちらを選択したら良いかが分からないなどの問題が表出してきました。 そこで、これまで暗黙的に共有されていた記述方法を言語化したり、まだチームの中で方針が決まっていなかった部分を GitHub Issues などで議論を深めていきました。 また自社での Compose のコード規約を考える上で、 API Guidelines for Jetpack Compose を参考に作成をしました。 コード規約の一部 コード規約は GitHub の wiki にまとめています。 コード規約が策定されたことによって、実装者が安心してJetpack Composeを利用することができるようになりました。 また成果物としてのコード規約の影響だけでなく、チームのメンバーでコード規約を作る過程にも価値があったと感じています。 コード規約では、いくか記述法として方法がある中で「なぜその選択をしたのか」の背景が必要になります。GitHub Issues などで議論を深める中で、「一般的にそう書かれているから」ではなく、「なぜその書き方が良いのか」について話し合うことができました。 様々な方法がある中で、TUNAGというプロダクトでなぜその選択をするのかについて、話し合うことができたのが良かったと感じています。 lintを導入 コード規約の作成に加えて、Compose の記述方法に関する lint をプロジェクトに追加しました。 今まで TUNAG 全体でも linter は未導入だったのですが、プレビュー用のComposable関数のprivate 修飾子のつけ忘れなど、どうしても抜け漏れが発生していました。 Compose のコード規約をチームで守っていくために linter の導入を決めました。 linter としては、 detekt を採用しました。 外部から Compose の lint のルールセットを追加できる点であったり、潜在的なバグの検出などのルールが標準で用意されている点で detekt を選択しました。 採用したルールに関しては、自分たちで作成したコード規約をもとに、必要なものを取り入れる形で決めています。 また linter による指摘を GitHub Actions の reviewdog を使って、PRでコメントされるようにもしています。 reviewdogによるlintのワーニング通知 これによってレビュワーによるレビューの前から、問題を検知することができるようになりました。 マルチモジュールのアップデート TUNAGでは、2020年ごろからマルチモジュールの導入を行っていました。 しかし、この当時のマルチモジュール化は細かい責務分けができていなかったため、むしろ負債になっている状態でした。 そこで2023年ごろから、責務分けなどを考慮した上でモジュールを再編していました。2024年はそれをさらに進化させ、モジュールを介した画面遷移を行うためのNavigationモジュールの作成を行いました。 マルチモジュールのアプリ構成では、モジュールを横断した画面遷移は依存関係が循環してしまうため、機能ごとでモジュールを切ることができませんでした。 モジュールが膨大になってくるとそのままビルドの速度にも影響します。機能をモジュールで分割できずappで実装することになり、ビルドの速度やJetpack Composeのプレビューに時間がかかる状態になっていました。 Navigationという画面遷移の抽象のみを持つモジュールを用意し、遷移実装をappで持たせることで、モジュールの依存関係が循環しないような形で実装をすることができました。 この実装が用意されたことで、2024年からは機能ごとにモジュールを分けることが可能になり、新機能に関しては新しい機能モジュールとしてスムーズに開発を進めています。 アプリの起動のフローの整理 アプリ起動処理のフローの整理を行いました。 元々はタイムラインの機能を提供するMainActivityにすべての実装がありました。そのためMainActivityの実装が非常にファットになっており、本来のタイムラインのために実装したい処理との区別がつかないような状態になっていました。また新たに起動時に処理させたいことがあっても、現在の処理を理解することが障壁になっており、機能追加時の障害にもなっていました。 それらを解消するために、起動の処理を整理し、MainActivityからの引き剥がしを行いました。 これにより、起動時にはどのような順番で処理が行われて、処理に応じたユーザーへの表示が明確になりました。 アプリの起動フロー再構成時に利用したメモ Android15対応 2024年秋に安定版がリリースされ、提供されている Android15 の対応を実施しました。 TUNAGプロジェクトとしては、そこまで大きな対応はありませんでしたが、edge-to-edge の対応が全画面に対して必要となりました。 edge-to-edge 対応とはAndroidのシステム領域である「ステータスバー」や「ナビゲーションバー」まで画面の描画領域を広げることができる機能です。 edge-to-edge の提供自体は過去から提供されていましたが、Android15 以降を targetSDK に設定しているアプリでは、強制的に適用されるようになりました。 TUNAGのAndroidプロジェクトはほとんどの画面でActivityベースで開発が行われているため、すべての画面において edge-to-edge の対応を行う必要がありました。 今回の対応としては、edge-to-edge で利用できるようになった領域に関しては従来通り透過をしないという暫定的な対応をしました。 今後よりネイティブアプリとして真価を発揮できるよう、画面に応じてナビゲーションバーの領域を一部透過するなど適宜対応していく方針となっています。 Kotlin 2.0への更新 Kotlin2.0へとメジャーバージョンの更新を実施しました。 TUNAGでは通常Kotlinのリリースの1ヶ月以内でのプロジェクトへの導入・リリースを目指しています。ただ今回はメジャーバージョンの更新であったため、慎重に検証を行いました。 結果としては、TUNAGにはそこまでKotlinのバージョンに依存しているライブラリが少なかったため、大きな問題もなく上げることができました。 Kotlin 2.0 へのアップデートでの大きな目玉としては、K2コンパイラへ移行があります。 ただK2コンパイラが Android Studio で利用可能になった当時はアルファ版であり開発に支障をきたすレベルのバグが存在していました。年末時点でK2コンパイラーを普段の開発で利用しているメンバーはおらずその早さはまだ実感できていません。 今回チームで2024年を振り返ったタイミングで、改めてK2コンパイラを使ってみようとなり、K2コンパイラの性能についてはこれからチームで検証していくこととなります。 PicassoからCoilへの移行 2024年11月に Picasso が非推奨となり、 Coil への移行が推奨されることがアナウンスされました。 TUNAGアプリは2018年当時からPicassoを利用しており、かなりの部分でPicassoに依存していました。 2023年からは Jetpack Compose で実装している部分に関しては一部 Coil の利用していましたが、過去に AndroidView で実装された部分に関してはすべてPicassoが利用されていました。ただ現在は Jetpack Compose での実装がメインとなり、TUNAG においては Coil がデファクトスタンダードになりつつあることを踏まえて、AndroidView で実装された箇所に関してもこの機会に Coil に移行する措置を行いました。 元々 Jetpack Compose のために Coil を導入したときにシングルトンの ImageLoader インスタンスの実装を行っていたため、両ライブラリで多少の違いはあったものの単純な置き換え作業となりました。 Markdown の検証 TUNAGの投稿では、マークダウンを利用することができます。 今まではWebViewのHTML表示などを利用して騙し騙しにマークダウンを提供していましたが、アプリケーションとしてよりWebViewに依存しないような構成にするために、TextViewベースのマークダウン表示の技術検証を行いました。 こちらは Markwon というライブラリをカスタマイズして、TUNAGでのマークダウンの書式が適用されるようにしました。 現在は技術検証が終わった段階で未リリースですが、これから順次アプリ内のマークダウンの表示を、こちらのネイティブベースのものに置き換えていく方針です。 最後に2025年に向けて 今回は2024年にTUNAG Androidアプリにて行った技術的な変化と挑戦を紹介しました。 こうして並べてみると、結構様々なチャレンジを行ってきたんだなと感じます。 機能開発だけでなく、アプリ開発におけるプラットフォームの改善にもより一層力を入れて、機能開発のベースラインを向上し、生産性の向上を目指しています。 株式会社スタメンでは、2025年より一層開発部門のギアを上げていくために全方向で開発メンバーを募集しています。 herp.careers
みなさんこんにちは、プロダクト開発部でTUNAGの開発をしている 小松 です。 先日行った社内イベント「BKP(ベスト開発ピッチ)」について紹介します! 今回のイベントは、プロダクト組織(エンジニア、PdM、プロダクトデザイナー)とカスタマーサクセス部(以下、CS部)が一緒になって取り組んだ初めての試みでした。 普段の業務ではなかなか伝えきれない「プロダクト開発の裏側」や「日々の活動や成果」を共有する場として開催し、大いに盛り上がりました。 BKPとは? 「BKP(ベスト開発ピッチ)」は、プロダクト組織が日々の成果や活動をピッチ形式で発表し、共有し合うイベントです。 もともとは、CS部で毎月恒例の「BKP(ベスト更新ピッチ)」がきっかけとなりました。CS部では、BKPで共有された取り組みが他のメンバーに受け継がれ、成果につながるという好サイクルが生まれています。 今回はCS部のメンバーからの提案を受け、この良い文化をプロダクト組織でも取り入れようと、企画段階からCS部と一緒に進め、プロダクト組織でも初めて実施することとなりました! プロダクト組織のBKPでは日々の活動や成果を共有しながら、メンバー間や部署間の連携を深め、称賛の文化を育むことを目的としてます! 開催の背景と目的 目的 プロダクト組織のナレッジを可視化 隠れた貢献の表層化・称賛の文化を育む 部門間の相互理解を深め、より良いサービスを届ける プロダクトをより良いものにするには、CS部とプロダクト組織の協力が欠かせません。 CS部は日々お客様からのフィードバックを集め、プロダクト改善のヒントを提供してくれています。一方で、プロダクト組織もその声を受け、新しい機能の開発や改善に取り組んでいます。 ただ、プロダクト開発部とCS部間の活動内容が見えづらいという課題もありました。 そこで、「BKP」を通じて、プロダクト組織が普段どのように改善や新機能の開発に取り組んでいるかを共有し、部門間の連携を深める場を作りました。 CS部とプロダクト組織が密に連携することで、スピーディーかつユーザーに価値のあるプロダクトを届けることを目指しています。 (取り組みの詳細は スタメン公式note でご覧ください。) 当日の様子 当日は、オンラインで開催され、6名のメンバーがそれぞれのテーマでピッチを行いました。 発表では、プロダクト改善の裏側や、未来のビジョン、新しい機能開発に込めた思いなどが語られました。 タイトル 登壇者 よりアプリらしさを出すために おしん 自動化しませんか? まっきー 管理画面の情報設計を見直した話 森田かすみ きれいなコードと責務のお話 hisayuki_mori レガシーコードDestiny〜本音を論じたい〜 カーキ プラットフォーム部のとある一日 uuushiro CS部からは「改善の裏にこんなストーリーがあったんですね」「新しい機能の背景がわかって嬉しい」といったコメントが寄せられ、互いの活動への理解が深まる時間となりました。 また、投票によるピッチ優勝者の表彰も行いました。もっとも多く票を集めたのは、まっきーさんの「自動化しませんか?」でした! プロダクト運用の効率を大幅に向上させた自動化の取り組みについて、具体例を交えながら分かりやすく説明しており、参加者から高い評価を得ました。 優勝したまっきーさんを始め、登壇したメンバーを皆で賞賛し、楽しい雰囲気の中でイベントを締めくくることができました! 今回のイベントを実施して感じたこと 1人1人の手で高めるプロダクトの価値 プロダクト組織の業務は、単にソフトウェアを作るだけではありません。 私たちは、部門を超えた協力の中で、より良いプロダクトをスピーディーに実現することを目指しています。 今回の「BKP」では、各メンバーが自身の取り組みを発表し、普段の業務ではなかなか共有できない知見や経験を共有する場となりました。 発表の中で感じたのは、「プロダクトをより良くしたい」という思いに基づいた真剣さと情熱です。 一人ひとりが主体的に発表し、他のメンバーと意見を交わす中で、チーム全体の結束がさらに強まったと感じています。 部門を超えたコラボレーションと一体感 また、スタメンでは、部門間の距離が近く、気軽に話しやすい環境が整っているため、こうしたイベントが自然体で進むのも魅力の一つです。 部門を超えた取り組みを通じて、多角的な視点を得ながらプロダクトづくりを進められるのは、スタメンならではの特徴だと思います。 このような環境の中で、メンバー全員が一体感を持ってプロダクトを磨き上げる姿勢を改めて実感しました。 今回の「BKP」をきっかけに、CS部との連携をさらに強化し、TUNAGをご利用いただく皆さまに価値を届けることで、感動や幸せが感じられるプロダクトを目指していきます。 採用情報 スタメンでは、プロダクト開発に関わる全ての領域でプロダクト職種の採用をしています。 もしご興味を持っていただけたら、下記からご応募ください! herp.careers herp.careers
この度、株式会社スタメンは、2024年12月05日(木)〜06日(金)の2日間、オンライン & オンサイトで開催される「プロダクトマネージャーカンファレンス 2024(pmconf 2024)」に、Silverスポンサーとして協賛します! カンファレンス情報 名称 :プロダクトマネージャーカンファレンス 2024(pmconf 2024) 開催日時:2024年12月05日(木)〜12月06日(金) 場所 :DAY1(オンライン)、DAY2(オンサイト:東京都大田区羽田空港2丁目7−1羽田エアポートガーデン) 参加方法や詳細については、下記公式サイトをご覧ください。 2024.pmconf.jp 当社スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG(ツナグ) 」を開発・提供しています。 2017年のサービス提供開始当初から、TUNAGは当社の成長を牽引してきたプロダクトです。 今回初めて、プロダクトマネージャーカンファレンスのスポンサーをさせていただきます。 当日のブース出展はありませんが、弊社からはPMの2名が現地参加します! オンサイト参加の方は、ぜひ現地で交流しましょう! おわりに プロダクトマネージャーカンファレンス 2024の2日間を通して、プロダクトマネジメントに対する学びを深め、よりよりプロダクトづくりに活かしていきたいと思っております。DAY2では、現地参加の皆様とお会いできることを心待ちにしております! 宣伝:直近の事業やプロダクト組織の取り組みもぜひご覧ください! 10→100フェーズを最前線で - デスクレスSaaS TUNAG(ツナグ)のProduct Managerをやる面白さ note.com スタメン技術ロードマップ 2025-2026 note.com 採用情報 スタメンでは、プロダクトマネージャーに限らず、全ての領域でプロダクト職種の採用をしています。 もし興味を持っていただけたら、下記からご応募ください! herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
はじめまして。TUNAGプロダクト開発部の勝間田です。2024年9月より株式会社スタメンにジョインしました。 2024/10/25 ~ 26で開催された Kaigi on Rails 2024 に当社からは、7名のメンバー(1人写真に入れず。。)で現地参加させていただきました。 Kaigi on Railsは「初学者から上級者までが楽しめるWeb系の技術カンファレンス」をコアコンセプトにしています。 普段Railsを使う中で感じた課題・困難とその解決策がセッションになることが多く、日々の開発に役立つような学びの多いカンファレンスです。 会場の様子 セッション会場は「Hall Red」と「Hall Blue」に分かれており、それぞれが視聴したいセッションを自由に選べる形式でした。 「Sponsor Booth Area」にはさまざまなブースが出展されており、楽しいコンテンツが豊富に用意されていました。 体験を通じて「このプロダクトをこの人数で運営しているのか」「意外とシンプルな構成だな」といった発見や驚きもありました。 また、「わいわい部屋」と「もくもく部屋」が用意されており、一息つきたい時や急な業務対応ができる環境もありました。 フロアマップ スタメンは Silver Sponsor として協賛させていただきました。 スポンサーボード 気になったセッション 約9000個の自動テストの時間を50分から10分に短縮、偽陽性率(Flakyテスト)を1%以下に抑えるまでの道のり speakerdeck.com テスト時間を短縮するためのさまざまな手法が、導入難易度も含めて丁寧に解説されており、とてもありがたい内容でした! 私自身もこの課題に向き合い、紹介された手法をいくつか試した経験があるため、勝手に親近感が湧いてしまいました(笑)。 Flakyテストも確実に減らされており、最終的にテスト時間やCI費用が大幅に改善されていました。 同じような課題に直面した際は、この内容を思い出してみようと思います。 推し活のハイトラフィックに立ち向かうRailsとアーキテクチャ speakerdeck.com ハイトラフィックなイベント物販サービスにおける在庫の確保と決済の対処方法についての内容でした。 具体的には、従来は「商品ID」と「在庫数」を1つのレコードで管理しており、ハイトラフィックな環境では行ロックによるデッドロックが頻発する問題がありました。 これを「1在庫1行」のデータ構造に変更することで、デッドロックを回避する手法が紹介されていました。 当時の状況や実際に起きた問題を、アイデアで解決していくお話が痛快で、とても楽しかったです! Data Migration on Rails speakerdeck.com Railsアプリでのデータマイグレーションについて、代表的な手法とそれぞれのメリット・デメリットをが紹介されていました。 これまで、手法についてあまり深く考えたことはなく、その時々のプロジェクトや状況に応じて選択していたことに気づかされました。 もしチームとして明確な方針が固まっていないのであれば、今回の内容を参考に話してみるのも良さそうです。 また、セッションで紹介されていた maintenance_tasks gemは権限管理や管理画面を提供しているみたいで気になるので今度実際に触ってみようかと思います! アーカイブ動画が公開されたら現地で視聴できなかったセッションも見てみようと思います! 同じくオフライン参戦したエンジニアの感想 まっきー : Kaigi on Railsは初参加だったのですが、実践的な内容のセッションが多くあり、持ち帰れる物の多い充実した2日間でした。 特に印象に残ったセッションは Identifying User Identity です。Railsアプリケーションをそれなりの期間運用しているとどうしてもユーザーモデル周辺が肥大化しがちなのですが、これに対するアプローチとして新たな視点を得ることができました。 また各企業のブースが面白く、お弁当も美味しかったりと、コミュニティとしての素晴らしさを体験することができました。機会があれば運営として参加もしてみたいと思えました。 speakerdeck.com 最後に 今回、個人として初めてオフラインのカンファレンスに参加しました。 福利厚生の一環として、参加費を負担していただき、業務としてこのような機会をいただけたことに感謝しています! Railsエンジニアの方々との交流や会場で感じた雰囲気は、オフラインでしか得られないもので、より一層研鑽への意欲が高まりました。 またカンファレンス開催にあたりご尽力いただいた運営スタッフの皆様に心より感謝申し上げます! 採用情報 スタメンでは、Ruby on Railsエンジニアに限らず全技術領域で、プロダクトを成長させていくエンジニア、デザイナー、プロダクトマネージャーの方を募集しています。 herp.careers
みなさんこんにちは、プロダクト開発部でAndroidアプリを開発している カーキ です。 先週の10月25日に開催された mobile.stmn にて「Composeで敷き詰めるUIをどうやって作るか」というタイトルで発表をしました。登壇した資料自体はSpeakerDeckにも公開をしていますが、せっかくならと思いテックブログでも公開してみることにしました。 導入 タイトルに「敷き詰めるUI」と書いていますが、これは以下の画像のように水平・鉛直方向へ要素が敷き詰められるようなレイアウトを指しています。 敷き詰めるレイアウトの例 このようなレイアウトをJetpack Composeで実現する方法として、2つのレイアウト方法が提供されています。 Lazy〇〇Grid Flow〇〇 Lazy〇〇Gridとは、LazyVerticalGridやLazyHorizontalGridなどに代表されるレイアウトコンポーネントです。またFlow〇〇とは、FlowRowやFlowColumnなどに代表されるレイアウトコンポーネントです。それぞれのレイアウトコンポーネントに関して、以下で基本的な性質から紹介していきます。 Lazy〇〇Gridについて 基本性質 名前の通り Lazy〇〇Grid は格子状のレイアウトを遅延表示することができるレイアウトコンポーネントになります。LazyColumnやLazyRowと同じようにcontentブロック内では、 item や items などのメソッドが利用できます。 主にLazyVerticalGridとLazyHorizontalGridという2つのコンポーネントに分けられ、それぞれ以下のように要素が敷き詰められます。 Lazy〇〇Gridの並び方 LazyVerticalGridは垂直方向へ敷き詰めが行われ鉛直方向にスクロール可能になり、LazyHorizontalGridは鉛直方向へ敷き詰めが行われて垂直方向へのスクロールが行われるため、注意が必要です。 LazyStaggeredGridについて LazyVerticalGrid, LazyHorizontalGridでは、格子状のレイアウトになるため、要素の大きさは均一になります。ただこれらのレイアウトと近縁関係にある LazyStaggeredGrid を利用することで高さもしくは、横幅の大きさを可変なものとしてレイアウト可能になります。 公式ドキュメントより LazyStaggeredGrid の実装例 LazyStaggeredGrid は執筆時点(2024/11/01)で Experimental なレイアウトとなっています。 GridCells LazyHorizontalGridでの格子の敷き詰め方は colums というパラメータによって決まります。(LazyHorizontalGridの場合は rows というパラメータ) columns は GridCells を継承したクラスを要求しており、 compose.foundation では以下の3つのクラスが用意されています。 GridCells.Fixed GridCells.Adaptive GridCells.FixedSize 1. GridCells.Fixed Fixedでは、一列の中に配置する要素の個数を指定することができます。 GridCells.Fixedで指定した場合 指定された個数に従って要素の大きさが決まります。 2. GridCells.Adaptive Adaptiveでは、一列中の要素の幅の最小値を指定することができます。(LazyHorizontalGridの場合は高さの指定になります) GridCells.Adaptiveで指定した場合 指定された幅の最小値に従って表示することの可能な個数分配置されます。指定しているのはあくまで最小値になるため、親のレイアウトの幅が88.dpで、Adaptive(20.dp)と指定した場合は、一列中に4つの要素が配置され、その幅は22.dpとなります 3.GridCells.FixedSize FixedSizeでも、一列中の要素の幅(もしくは高さ)を指定することで配置を指定します。ただAdaptiveと異なっているのは、列中で余った領域に関してはArrangement.Horizontal の指定に従うようになっています。例えば以下の画像では、Arrangement.Horizontalの指定を Arrangement.spaceBy(8.dp) としているため、要素間の間隔を8.dpにするために余剰分に関しては、画面右に寄せられています。 GridCells.FixedSizeで指定した場合 ヘッダーの表示 LazyGridのitemとして、ヘッダー要素を表示させることができます。ただ普通にitemのブロックに要素を入れただけでは、下画像のようにグリッドの要素として組み込まれてしまいます。 item のブロックに単純にヘッダー要素を入れた場合 以下のように span を実装する必要があります。 @Composable fun LazyGridHeaderSample() { LazyVerticalGrid( columns = GridCells.Fixed( 3 ) ) { item( span = { GridItemSpan(maxCurrentLineSpan) } ) { Text(text = "Header" ) } items( 10 ) { index -> ... } } } span に maxCurrentLineSpan で指定すれば、空いているGridのスペース分の領域をコンテンツブロック内で確保することができます。上記のコードで並べた結果が以下のようになります。 GridItemSpanを利用してitem のブロックに単純にヘッダー要素を入れた場合 GridItemSpanを利用することでLazyVerticalGridを利用してヘッダーを表示することができます。 Flowレイアウト 基本性質 Flowレイアウトは 公式のドキュメント では、「ColumnやRowのコンテナのスペースが不足した時に、要素が次の行に流れ込む性質を持ったコンポーネント」と説明されています。次の行に流れ込む性質を持ったColumnやRowと説明されている通り、レイアウト方向に応じてFlowColumnやFlowRowなどが存在します。Flowレイアウトは執筆時点(2024/11/01)で、ExperimentalLayoutApi とされており、試験運用版という扱いになっています。 Flowを使うことで以下のようなタグの表示を実現することができます。 公式ドキュメントよりFlowレイアウトの例 Flowレイアウトでは、上記のタグのように要素を並べていく方向の幅を可変にすることができます。LazyVerticalGridでは基本的に並べる方向の幅は全て均一になります。格子状に並べる上ではLazyGridが適していますが、サイズの異なる要素を順に並べていくのはFlowレイアウトが適しています。 Arrangement Flowレイアウトの敷き詰め方は、 HorizontalArrangement と verticalArrangement という引数に何を渡すかによって決まります。これらのパラメータへの指定によって右寄せ・左寄せ・等間隔など様々な配置方法を指定することができます。 この辺りは 公式のドキュメント が詳しいので説明はそちらに譲ります。 2つの使い分け ここまでLazyGridとFlowレイアウトの性質について紹介してきました。ざっくりそれぞれのレイアウトコンポーネントの特徴をまとめると以下のようになります。 LazyGridは、格子状に要素を敷き詰めるのに適したレイアウトコンポーネント Flowレイアウトは、折り返しを考慮してものを敷き詰めたい時に適したコンポーネント この2つの比べると格子状の場合はLazyGridで、それ以外の場合はFlowを選択するのが良いように感じます。ただLazyVerticalGridはLazyなレイアウトになるので、同一方向のLazyのレイアウトを親や子に持てないなどといった、それぞれ採用判断に影響する差異が存在するので紹介します。 LazyGridが向いているケース スクロール方向と交差する方向のサイズが固定である 表示量が多いなど、遅延して表示したい要件がある Experimental な機能を利用できない Flowレイアウトが向いているケース 要素の大きさがものによって変わる 遅延して表示させる要件がない グリッドの部分のみ背景を変えたい要件がある 「Flowレイアウトが向いているケース」の最後の項目だけより具体的な事例を出していますが、TUNAGの開発中にこのパターンに当たり、Flowレイアウトを採用したという背景があります。 具体的には以下のような画面になります。(該当の画面を抽象化して示しています) 特殊な実装例 こちらの画面では均等に要素を並べるようなUIを想定していたため、LazyVerticalGridの採用を検討していましたが、グリッドの部分のみ背景色を変更することがLazyGridではできません。この画面はスクロールも要求していたので、LazyVerticalGridで実装する場合画面全体をLazyVerticalGridでレイアウトする必要がありました。ただ特定のitemsのブロックの中でのみパディングや背景色の変更を行うことが難しかったため、FlowRowを採用しました。 何か複雑に組み合わせることで、LazyVerticalGridの利用も可能だったかもしれませんが、今後のメンテナンス性も考えると、シンプルな利用で表現することができるFlowRowに寄せることとしました。 LazyGridとFlowレイアウトでは、それぞれ向いているレイアウト方法がありますが、どちらのレイアウト方法でも実現することができるのもまた事実です。基本的にはそれぞれのレイアウトコンポーネントの基本性質にあった方法を取れるのが良いですが、それでも実現することが難しい場合・実装があまりにも複雑になりすぎてしまう場合があります。それぞれのメリット・デメリットのトレードオフを考えて実装されるのが良いかと思います。 まとめ 今回のブログでは、LazyGridとFlowレイアウトの紹介と比較を行いました。 どちらでもできること・どちらかにしかできない表現があるため、それぞれの性質を理解した上で、どちらを利用するのかを要件に沿って選ぶのが良いと思います。 株式会社スタメンでは、チームで議論を深めながらJetpack Composeの利用の幅を広げています。Jetpack Composeが大好きなAndroidエンジニアの方はぜひ一度カジュアル面談からお話を聞いてみてはいかがでしょうか。 herp.careers herp.careers
こんにちは。 この度、株式会社スタメンは、2024年10月25日〜26日の2日間、有明セントラルタワーホール & カンファレンスにて開催される「Kaigi on Rails 2024」に、Silverスポンサーとして協賛します! カンファレンス情報 名称 : Kaigi on Rails 2024 開催日時 : 2024年10月25日(金)〜10月26日(土) 場所 : 有明セントラルタワーホール & カンファレンス + オンライン 参加方法や詳細については、下記公式サイトをご覧ください。 kaigionrails.org 当社スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG(ツナグ) 」を開発・提供しています。 TUNAGの開発では 2017年のサービス提供開始当初から Ruby on Rails を採択してきました。 リリース当初から、開発を推し進めることができているのは、Rails関連の技術コミュニティの支えがあってこそであり、 昨年 に引き続き 今年も協賛させていただく運びとなりました。 当日のブース出展はありませんが、弊社からはエンジニア、HR含め7名が現地参加します! オフライン参加の方は、ぜひ現地で交流しましょう! おわりに Kaigi on Rails の2日間を通して、Railsエンジニアの皆様だけでなく、様々な技術領域のWebエンジニアの皆様とお会いできることを心待ちにしております! 宣伝:直近の事業やプロダクト組織の取り組みもぜひご覧ください! PIVOT:【日本の労働人口の約半分】飲食・小売・物流…ノンデスクワーカー業界を変える/低い労働生産性 解決のカギは組織エンゲージメントの向上/組織づくりを支援する「TUNAG」とは www.youtube.com スタメン技術ロードマップ 2025-2026 note.com 10→100フェーズを最前線で - デスクレスSaaS TUNAG(ツナグ)のProduct Managerをやる面白さ note.com 採用情報 スタメンでは、Railsエンジニアに限らず、全ての領域でエンジニアを募集しています。 もし興味を持っていただけたら、下記からご応募ください! herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
TUNAG プロダクト開発部 第2グループの カーキ です。 先週9月11日から13日にわたって開催されたDroidKaigi2024にプロダクト開発部のメンバー4人で参加しました。 参加メンバーでパシャリ📸 今年はサポータースポンサーとしてスタメンもイベントにスポンサードしています。 DroidKaigiスポンサー紹介のスライド DroidKaigi振り返り Workshop Day 初日は JetBrains の方を講師に招いて、Kotlin Multiplatform(以下:KMP)を使ったAndroidアプリ・Webアプリ・デスクトップアプリをビルドするワークショップが開催されました。JetBrains の方に直接質問もできる貴重な機会でした。 ワークショップの様子 ワークショップでは Fleet という JetBrains が KMP のために開発した IDE を利用して行われました。Fleet という IDE は知っていたものの、思った以上にサクサクと開発できて感動しました。ビルド時間が長いなどの問題はありましたが、プレビュー版ゆえのものだと思っておきます🤫 またワークショップでは Compose Multiplatform(以下:CMP) のワークもありました。Android 開発での UI 作成のフレームワークがWebやデスクトップアプリでも全く同じ体験として実現できるのには驚きました。 今回ワークショップに参加をしてみて、KMPとCMP 思ったよりもいけるぞ!と感じました。CMP は一部アルファ版のものもありビルドターゲットによっては、まだ不安はありますが、CMPを使った開発の快適さを感じました。 のぼりの前で📸 2,3 日目のセッション 2日目以降では各ルームでセッションが開催されました。 今年もセッションルームには代々の Android Studio のバージョン名になった動物たちの名前がついていました(カワイイ-) 各ルームのキャラクター 2日間で本当にたくさんのセッションがあり、何を聞きに行くのかも毎回迷ってしまいました。気にはなっていたが渋々見ることができなかったセッションもあるので、それらは公式があげているYouTubeの動画をこれから見ていこうと思っています。 スタメンメンバーが見たセッションの中から印象に残ったセッションをいくつか紹介します。 Androidエンジニア カーキ(自分) 仕組みから理解する!Composeプレビューを様々なバリエーションでスクリーンショットテストしよう 自分が印象に残ったセッションは『 仕組みから理解する!Composeプレビューを様々なバリエーションでスクリーンショットテストしよう 』です。Compose によって作成されたビューはテストがしやすいということは知っていたものの、現状のプロダクトコードには Compose のテストは存在していなかったので、プレビューを利用してどのようなテストが行えるのかが気になっていました。様々なテストツールを利用することで複数プレビューのパターンに対応することができることが段階的に説明されており、中長期的な目線でスクリーンショットテストを導入するかどうかを検討する上での材料になりました。 Androidエンジニア ケンタ PDF Viewer作成の今までとこれから AndroidにおけるPDFビュワーの歴史から細かな実装まで、とても詳細に解説されていて良いセッションでした。 Androidエンジニア ヒビキ たすけて!ViewModel ViewModelの役割や説明を踏まえてよくある誤りから責務の分離がとてもわかりやすかったです。ComposeとViewModelの強い関係性からもこのセッションを聴いて再認識できてよかったです。 CTO 野口 昨年に続き、DroidKaigi 2024に参加し、Android開発のトレンドを肌で感じることができました。特に、Jetpack Composeが十分にデファクトスタンダードになってきている点や、Kotlin Multiplatformの他社導入状況について議論することができました。ビジネス的には競合であったりする会社に属しているエンジニアと会話し、新たなコミュニティに繋がることができたのも技術コミュニティあってのことだと認識しています。スタメンでは今後もより高品質なAndroidアプリ開発を目指していきます。 さいごに 初日のワークショップや、2日目からのセッションはもちろんですが、DroidKaigiには美味しいコーヒーの提供やネイル体験、プリクラなど、参加者が楽しめる仕組みが沢山ありました。 自分は今回のDroidKaigiがオフラインでは2度目の参加になりますが、本当に3日間ずっと充実していました。 セッションで得た情報をそのままにせず、チームで共有をして日々の開発に活かしていくために、チーム内で共有会を開催しようと思っています。 採用情報 株式会社スタメンではAndroid領域に限らず、様々な領域でエンジニアを募集しています。 herp.careers
こんにちは! 組織開発部のTookaです。 株式会社スタメンは、2024年9月11日〜13日の3日間、ベルサール渋谷ガーデンにて開催される「DroidKaigi 2024」に、サポータースポンサーとして協賛します! スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG(ツナグ) 」の、Android向けアプリケーションを開発・提供しています。 より多くのユーザーが快適にTUNAGをご利用いただくため、当社エンジニア組織ではモバイル先行の開発体制や開発プロセスにシフトしています。 モバイル先行の開発を推し進めることができているのは、Android関連技術コミュニティの支えがあってこそであり、昨年に引き続き今年も協賛させていただく運びとなりました。 参考:これまでのスポンサーやAndroid関連のテックコミュニティでの取り組み DroidKaigi 2023にスポンサーとして参加しました! スタメンが主催で開催しているモバイル開発の勉強会「mobile.stmn」が1周年を迎えました DroidKaigi.collect { @Nagoya } ※会場提供のみ 本カンファレンスへの協賛を通して、これからのAndoridアプリ開発者コミュニティの発展を後押ししていきます! イベントを一緒に盛り上げていきます! カンファレンス概要 開催:2024年9月11日(水)~ 9月13日(金) 場所:東京都渋谷区南平台町16-17 住友不動産渋谷ガーデンタワー 1F・B1 主催:一般社団法人DroidKaigi 詳しくは公式サイトをご覧ください。 2024.droidkaigi.jp 当日のブース出展はありませんが、弊社からはエンジニア4名が現地参加します! オフライン参加の方は、ぜひ現地で交流しましょう! 採用情報 スタメンでは、Andoridエンジニアに限らず、全ての領域でエンジニアを募集しています。もし興味を持っていただけたら、下記からご応募ください! herp.careers
こんにちは!TUNAG iOSアプリ開発担当のおしん ( @38Punkd )です。 スタメンは今年はシルバースポンサー枠での協賛なのでブース出展はありませんが、 モバイルチームの朝倉( @asashin227 )、プロダクトHRの東岡( @Tooka_91 )と私の3名で会場に現地参加してきました。 昨年の参加報告はこちら 👇 tech.stmn.co.jp 今回はブースをまわるだけでなく、セッションを聴く時間も多く確保できたので、色々なセッションを聴いて周りました。 その中でも私個人として印象に残ったセッションをピックアップしました。 Day 0 - 前夜祭 8/22 App Clipの魔法: iOSデザイン開発の新時代 by log5 App Clipを使った、アプリデザインの共有方法の紹介がありました。 App Clipとは、iOS 14から搭載された機能で、特定のタスク等を素早く行うためのミニアプリのことです。 完全版のアプリをインストールせずに使用できるので、レストランでの注文などに使われることが多い印象です。 developer.apple.com 本セッションでは、この手軽さを利用してプロトタイピングツールとしての利用を紹介されていました。 新規に実装したUIコンポーネントをApp Clipで表示することで、デザイナーは、実際にiPhone端末上で、そのUIコンポーネントに集中して、触ることができます。 画面より小さい単位のUIに対して特にフィードバックを得やすく、とても斬新なアイデアだと感じました。 fortee.jp Day 1 - 8/23 iOS/iPadOSの多様な「ViewController」の徹底解説と実装例 by haseken iOSのViewを実装する際には必ずどこかしらでお世話になる UIViewController にまつわるお話でした。 UIKitだけでなくMapKit等の他のiOS向けUIフレームワークも合わせると、なんと80種類以上のViewControllerのサブクラスが存在していて驚きました。 私はiOS開発を始めてまだ2年半でまだまだiOS開発の歴史に疎かったので、とても勉強になりました。 fortee.jp Day 2 - 8/24 Swift 6のTyped throwsとSwiftにおけるエラーハンドリングの全体像を学ぶ by koher スタメンもSwift 6への移行準備を進めていますが、Strict Concurrencyへの対応だけでなく、Swift 6から使えるようになる新しい言語機能も、積極的に取り入れていこうと考えています。 その上で、Error型に準拠した型のエラーを投げる「Typed throws」は、どのタイミングで使用すべきか気になっていました。 koherさんのセッションでその疑問が解消されただけでなく、エラーハンドリングの基本的な考え方を学ぶことができました。 早速、今後のモバイルアプリ開発に活かせられそうです! fortee.jp 最後に 今年のiOSDCはSwift 6やクロスプラットフォームの話題が例年より多く感じ、iOS開発の時代の流れを感じました。 LT大会はユニークな発表ばかりで、終始目を丸くして見ていました。 懇親会では、昨年のiOSDCでお会いした方と今年もお会いしてお互いの近況をお話することができ、楽しく過ごすことができました。 昨年とは違った形で参加した今年も、暑い夏に負けないパワーを会場から頂きました!! 運営の皆さま、本当にお疲れ様でした! (LT用のサイリウムを配られ、待てずに点灯させちゃう筆者) 参加メンバーの感想 朝倉( @asashin227 ) 今年もiOSDCに参加できて非常に嬉しく思います。 今年はSwift 6対応やクロスプラットフォームの発表が目につき、直近の弊社の開発状況と似た課題を抱えた方が多い印象を受けました。 普段の開発の割合が多くはないため、必死に食らいつきながら発表を聞いていました。 昨年はブース運営を行なっていましたが、今年はフルで参加できたため久々のお祭り感を存分に楽しむことができました。 また来年、お会いできることを楽しみにしています。 東岡( @Tooka_91 ) 個人的には初iOSDC参戦、かつ今回はブース運営がなかったので、純粋に参加者の目線でも楽しむことができました。 私はエンジニアではないので、非エンジニアでも楽しめそうなセッションを選びながら参加していました! 技術的な知見がないとちょっと厳しいかなと思っていたのですが、4ラインのセッションのうち少なくとも1セッションは、技術的な知見の少ない私でも楽しめるものであり、普通に楽しめました。 スポンサー側の体験としても、運営の方が丁寧なコミュニケーションを取ってくださり、事前準備は決して多くありませんでしたが、スムーズに不安なく当日を迎えることができました。 改めてありがとうございました!来年もぜひ参加したいと思います。 採用情報 スタメンでは、iOSエンジニアに限らず、全ての領域でエンジニアを募集しています。もし興味を持っていただけたら、下記からご応募ください! herp.careers
こんにちは! プロダクトHRの東岡です。 株式会社スタメンは、2024年08月22日-24日の3日間、早稲田大学理工学部西早稲田キャンパスにて開催される「iOSDC Japan 2024」に、シルバースポンサーとして協賛します! スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG(ツナグ) 」の、iOS向けアプリケーションを開発・提供しています。 より多くのユーザーが快適にTUNAGをご利用いただくため、当社エンジニア組織ではモバイル先行の開発体制や開発プロセスにシフトしています。 モバイル先行の開発を推し進めることができているのはiOS関連技術コミュニティの支えがあってこそであり、 昨年に引き続き 今年も協賛させていただく運びとなりました。 本カンファレンスへの協賛を通して、これからのiOSアプリ開発者コミュニティの発展を後押ししていきます! イベントを一緒に盛り上げていきます! カンファレンス概要 開催:2024年8月22日(木)~ 8月24日(土) 場所:早稲田大学理工学部西早稲田キャンパス+ニコニコ生放送 対象:iOS関連技術およびすべてのソフトウェア技術者 主催:主催: iOSDC Japan 2024 実行委員会 詳しくは公式サイトをご覧ください。 iosdc.jp 当日のブース出展はありませんが、弊社からはモバイルチームの朝倉( @asashin227 )、青木( @38Punkd )、プロダクトHRの東岡( @Tooka_91 )の3名が現地参加します! オフライン参加の方は、ぜひ現地で交流しましょう! ノベルティについて 創業以来、約8年続いたコーポレートロゴを刷新し、ロゴが新しくなりました。 今回はその新ロゴを印刷したクリアファイルをノベルティとして用意しました。 ぜひ普段のお仕事や、勉強等でご活用いただけると嬉しいです! コーポレートロゴリニューアルの詳細はこちら stmn.co.jp おわりに、チャレンジトークンはこちら! iOSDCの3日間を通して、iOSエンジニアの皆様だけでなく、様々な技術領域のエンジニアの皆様とお会いできることを心待ちにしております! 現地でお会いした際はぜひお話ししましょう! チャレンジトークンは、下記です! #iOSDC_stmn 宣伝:モバイル開発のオフライン勉強会「mobile.stmn」をほぼ各月で定期開催中!次回、9/6(金)の参加者&LT登壇者募集してます! 「mobile.stmn」は、スタメン モバイルアプリエンジニアが主催するモバイルアプリ開発に関する勉強会です。 モバイルネイティブアプリやクロスプラットフォーム開発など、モバイルデバイス向けの開発や周辺の技術を中心に扱っています。 本イベントはオフライン(会場参加)のLT会を開催しています! モバイルアプリエンジニアの方やその領域に興味がある方であれば、どなたでも参加いただけます。 交流会も予定していますので、日頃のアプリ開発のあれこれなどについてお話ししましょう! stmn.connpass.com 採用情報 スタメンでは、iOSエンジニアに限らず、全ての領域でエンジニアを募集しています。もし興味を持っていただけたら、下記からご応募ください! herp.careers
はじめに 株式会社スタメン、プロダクト開発部モバイルアプリGでAndroidアプリを開発しているカーキ( @khaki_ngy )です。最近は、Google Gemini API ディベロッパーコンペに出すアプリを個人開発しており、賞品のデロリアンを狙っています🤩 スタメンでは名古屋のモバイルアプリ開発メンバーが主体となって mobile.stmn というモバイルアプリ開発のオフラインの勉強会を主催しています。mobile.stmnは隔月で開催しており、前回の開催でちょうど1年が経ちました。 イベントのバナー画像 今回のブログでは、mobile.stmn の1年間の振り返りと今後の展望について紹介をしていきます。 mobile.stmnとは この勉強会は、モバイルアプリ開発に携わる人・関心のある人を対象としたLT会です。社員1名と一般公募4名の計5人がLTを行い、モバイルアプリ開発に関する経験や知見を共有しています。LTのテーマはモバイルアプリ開発に関わることであれば自由です。過去にはモバイルアプリ開発の言語やフレームワーク、CI/CD、開発ツールに関することなど様々な発表がありました。 LT後は懇親会も設け、参加者同士が交流できる場を用意しています。お菓子やドリンクなどを用意し、和気藹々とした雰囲気で交流を楽しんでいます。 イベントの様子 イベントはスタメン名古屋本社のイベントスペースを利用して開催しています。 これまでのイベントについて 過去の登壇内容に関してはこちらのConnpassのイベントページをどうぞ mobile.stmn #1 mobile.stmn #2 mobile.stmn #3 mobile.stmn #4 mobile.stmn #5 mobile.stmn #6 スタメン名古屋本社のイベントスペースは無料で貸し出しも行っており、毎日何かしらのイベントが開催されています。 スタメンイベントスペースの様子 イベントスペースの利用に関心のある方は、こちらの資料もご覧ください。 株式会社スタメン イベントスペース貸し出しについて 開催の背景 mobile.stmnを開始しようとしたきっかけは 名古屋のモバイルアプリ開発を盛り上げたい と思ったからです。 まずmobile.stmnを開始した2023年には名古屋でモバイルアプリ開発に特化した勉強会がほとんど無い状態でした。またちょうどその時期はコロナによって勉強会が中止になっている勉強会も多々ある状況でした。 勉強会は社外の開発者のLTを聞いたり、交流する絶好の機会です。社外の開発者との技術交流などを通じて得た新たな知見を普段の開発に活かしたり、交流によって開発へのモチベーションも得ることができます。自分もオンライン・オフライン問わず様々な勉強会に参加して、学びを業務に活かすことはもちろん、交流という点でも楽しんでいます。 また勉強会をコミュニティとして考えると、地域に活発なコミュニティがあることも重要だと思っています。勉強会という場があることで、モチベーションが上がるだけでなく、同じ技術を学んでいる人が周りにいるんだ!ということも力になると思っています。自分個人の経験としても、学生の時に名古屋のモバイル開発の勉強会に参加をして、たくさんの勇気をもらったという経験が今のエンジニアとしてのキャリアに大きく寄与しています。 1年間開催してきた振り返り 1年間 mobile.stmn を運営してみて、いくつか気付きがあったので紹介していきます。 参加者を集めるのは大変 名古屋でモバイル開発の勉強会を始めて、一番最初に壁にぶつかったのは、参加者集めでした。 名古屋にもモバイル開発に携わるエンジニアの方はいらっしゃいますが、やはり東京や大阪といった大都市圏に比べると数は少なく、イベントの参加者集めには苦労しました。 イベントの初期段階では、他の勉強会に登壇し、自分の主催する勉強会を紹介したり、X(旧Twitter)などのSNSで積極的に情報発信したりするなど、イベントを知ってもらうための活動に力を入れていました。 これらの経験から、イベント告知の重要性を改めて実感しました。 チームでの勉強会の運営 mobile.stmnは自分個人ではなく所属しているモバイルアプリ開発チームの名古屋メンバー全員で運営をしています。 自分がやりたいです!と始めた勉強会ですが、一緒に主催しているチームのメンバー全員で取り組むことができたからこそ、ここまで継続して開催することができたと思っています。 勉強会1回をとっても当日の司会や受付、connpassページの作成、飲食物の購入など様々な準備が必要であり、1人の力で運営することは難しく、ましてや継続していくことは困難です。 きっかけ自体は自分だったものの、運営をチーム全員で取り組むことができたからこそ、ここまで継続できたと思っています。 定期的に登壇の機会を作ることができる このイベントでは、毎回社員がローテーションで登壇し、日頃の業務で得た知見や、新しい技術についての調査結果などを発表しています。発表したいテーマを持ち寄ることもあれば、チームでローテーションを組んで発表の機会を均等に与えることもあります。 この仕組みのおかげで、社員一人ひとりが定期的にプレゼンテーションの機会を得られるようになり、自然と『次は何を発表しようか』と、日々の業務や技術調査の際に発表ネタを探し始めるようになりました。 また、登壇経験が少ないメンバーにとっても、このイベントは貴重な機会となっています。主催イベントということもあり、外部のイベントに比べて参加のハードルが低く、リラックスした雰囲気の中で発表できるため、プレゼンテーションスキル向上のための良いトレーニングの場となっています。 継続は力なり mobile.stmnは、この7月に1周年を迎えました。1年という月日が経ち、リピーターの方も増え、少しずつコミュニティが形成されてきたことを実感しています。 定期的な勉強会を通して、参加者が継続的なつながりを確認する場としても機能していることに気付いてきました。 継続的に交流を行うことのできる場があると、2回目、3回目に参加した時に「前話してたあれどうなったんですか?」という会話など継続的なものとして交流を行うことができます。 技術的なスキルアップはもちろん、同じ目標を持つ仲間と交流することで、開発に対するモチベーションが向上し、日々の業務にも良い影響を与えていると感じています 今後に関して 今後も、隔月で開催しているLT形式のイベントを継続しつつ、新たな試みとしてワークショップ形式のイベントを企画検討中です。名古屋のモバイルアプリ開発コミュニティの拡大を目指し、モバイルアプリ開発に興味のある初心者の方々にも参加しやすい工夫を考えています。 mobile.stmnの次回の開催は、9月6日を予定しています。 次回イベント 下記のコンパスページで募集を開始していますので、参加をお待ちしています。 stmn.connpass.com
こんにちは。 株式会社スタメンで、Product HRをしている東岡 ( @tooka_91 )です。 今回は RubyKaigi 2024 の参加レポート記事です。 昨年の RubyKaigi 2023 から引き続き、2024年5月15日~17日の3日間、那覇文化芸術劇場なはーとにて開催された、RubyKaigi 2024 にスポンサーとして協賛し、ブース出展をしました。 当社からは、6名のメンバーで現地参戦させていただきました! カンファレンス当日や、ブースの様子をご紹介できればと思います! 今回のスポンサーブースについて RubyKaigi 2024では、Platinumスポンサーとブース出展をさせていただきました。 これまでもテックカンファレンスでブース出展は何度か行なってきましたが、今回は、ノンデスクワーカーの方をメインターゲットとしたデスクレスSaaS『 TUNAG 』で、昨年10月にリリースした新機能『 TUNAG ベネフィット 』の機能の一部をブースコンテンツに用いました。 実際のプロダクトの一部機能を利用し、参加者のみなさまに景品の当たる抽選にトライいただきました。RubyKaigi 2024のために、オーダーしたクッピーラムネが想像以上に好評いただき嬉しかったです。 参加者の皆さまに楽しんでいただけたので、良かったです! 今回ご用意したノベルティ スタメンスポンサーブースの様子 Mazさんも遊びに来てくださいました!ありがとうございました!(VP of Engineering 松谷と写真撮影いただきました。) スタメンブースにMatzさん @yukihiro_matz が遊びに来てくれました! TUNAGの抽選機能にもチャレンジしていただきました!ありがとうございます! #rubykaigi pic.twitter.com/H4fssgfGaQ — stmn, inc. Developers (@stmn_eng) 2024年5月16日 RubyKaigi初参戦のエンジニアメンバー感想 スタメンでエンジニアをしている近藤( @sei_kondo97 )です。 今回、初めてRubyKaigiに参加しました。 どのセッションも非常に興味深く感じましたが、特に関心を持っていたのは、Ruby 3.0に導入されたRBSについてです。全てのセッションに参加できたわけではありませんが、2024年はRBSに関する以下のセッションがありました。 Let's use LLMs from Ruby 〜 Refine RBS types using LLM 〜 Community-driven RBS repository Embedding it into Ruby code Good first issues of TypeProf 弊社ではRBSの採用はしておりませんが、型検査によるバグ検出の恩恵は非常に魅力的です。 一方で、Rubyの型に関してはまだコミュニティの方向性が定まっていない部分もあり、現時点で積極的に導入するのは難しいとも感じています。またRubyKaigiを通して、「Rubyに型は必要ない」というネガティブな意見も一定数見受けられ、これも今後の型導入を検討する際の参考になりそうです。 最も面白かったセッションは、 Ruby Committers and the World でした。 例えば、Ruby 3.4からfrozen_string_literalがデフォルトで有効になる対応が開始されますが、この議論も非常に盛り上がっていました。 Immutable String literal in Ruby 3 のようなやり取りがリアルタイムで展開されるのは非常に新鮮な体験であり、私にとってRubyコミュニティをより身近に感じられる時間となりました。 3日間の大盛況だったブースをやり切った翌日はVP of Engineeringの松谷( @uuushiro )の運転のもと、アメリカンビレッジと首里城を観光しました。沖縄を堪能しつつ、社内の参加メンバーともじっくり会話することができ、有意義な時間を過ごしました。 現在は名古屋に戻り、また普段通りに日々の開発に勤しんでいます。今後ますますRubyを盛り上げていけるように、Rubyをメイン言語の1つとしている弊社の TUNAG の成長やOSSへの貢献に励んでいきたいと思います。 最後に 今回はスタメンからもRubyKaigiに初参戦のメンバーが複数いましたが、国籍問わず、 多くのRubyistの方々が来場されており、改めて世界中で長く愛されている言語なのだと肌で感じました。 また、Rubyコミュニティならではの熱量を強く感じることができ、とても良い3日間を過ごすことができました。 毎日、朝早くから、夜遅くまでRubyKaigiがずっと続いているような感覚になり、とても幸せな時間でした。 Rubyを主要言語にプロダクト開発をしている私達にとって、世界中のRuby愛のあるエンジニアの方とお話ができたのはとても貴重な機会でした。開催中、ブースや交流会等でお話しいただいた皆さんありがとうございました! 来年は、ブースのコンテンツや、より多くの国籍の方と一緒に楽しめるよう英語力も磨き上げ、さらに各国の方と交流できるように準備していきたいと思います。 それでは、来年2025年は、松山でぜひお会いしましょう!! 採用情報 スタメンでは、Rubyエンジニアに限らず全技術領域で、プロダクトを成長させていくエンジニア、デザイナー、プロダクトマネージャーの方を募集しています。 もし興味を持っていただけたら、下記からご応募ください! herp.careers
こんにちは、スタメンで TUNAG の機能開発チームに所属している森( @hisayuki_mori )です。 今回、2023年の11月からスタートした新機能開発においてフロントエンド側の開発を担当しました。 この5ヶ月の間に新しくチャレンジしたことの紹介をします! チャレンジしたことまとめ 背景 詳細 Node.jsを18系から20系にアップデート Reactを17系から18系にアップデート Storybookの8.xをalpha版から導入 Biomeの導入 testing-liblraryの導入(v12)とアップデート(v15) やりきれなかったこと 最後に チャレンジしたことまとめ Node.jsを18系から20系にアップデート Reactを17系から18系にアップデート Storybookの8.xをalpha版から導入 Biomeの導入 testing-liblraryの導入(v12)とアップデート(v15) 振り返るといろいろなことにチャレンジできたなと思います。 それでは、これらを実現できた背景について話していきたいと思います。 背景 TUNAGにはユーザーが見る画面とは別に、管理者のみが見える画面が存在しています。 以前のブログ記事のリプレイスはTUNAGの中の ユーザー画面 と言われる箇所のリプレイスであり、 管理画面 は含まれていませんでした。 そのため、今回ユーザー画面側をリプレイスすることになった背景にある開発効率がよくない課題が管理画面にはそのまま残っていました。 背景についてはこちらの記事を参考にしてください。 tech.stmn.co.jp 今回の新規機能開発では、管理画面の実装ボリュームがそこそこ多かったため、現行のアーキテクチャでの実装を積み上げるのは避けたいと考えました。 せっかくユーザー画面をリプレイスしているので、アーキテクチャを見直すことで古い技術を捨てつつ、社内のスキルセットを合わせていきたいと思っています。 そこで、リプレイスは今はできないですが、今後の新規開発では可能な限りユーザー画面のリプレイス同様の実装に寄せ、切り離しプロジェクトが発足した際に備えたアーキテクチャでの実装を進めることにしました。 以前のブログ記事で、フロントエンドチームがフロントエンドのリプレイスを行っていることが紹介されています。 基本的な技術選定やアーキテクチャはフロントエンドリプレイスに追随しているため、こちらの記事を参照してください。 tech.stmn.co.jp 詳細 ここからは実際にチャレンジしたことの詳細を書いていきます。 Node.jsを18系から20系にアップデート 開発が始まった当初はNode.jsは18系のままでしたが、まずはユーザー画面リプレイスに合わせて 20.9.0 まで上げました。 管理画面はTUNAGのリポジトリに同居していますが、それぞれのディレクトリごとに独自の package.json を保持しています。 そのため、各ディレクトリごとにNode.jsのバージョンも指定できます。 大まかなディレクトリ構成は以下の通りです。 ├ .storybook ├ app │ ├ javascript │ ├ (~~~) │ ├ 新機能の管理画面 👈 今回の実装を配置する場所 │ ├ frontend │ ├ 管理画面 │ | ├ package.json 👈 現行管理画面のpackage.json │ ├ biome.json ├ esbuild.config.mjs ├ package.json 👈 package.jsonはrootに配置 今回の新機能の管理画面用の package.json は、現在の実装の関係でルートに配置する必要があるため、そのようになっています。 新しいディレクトリに実装を始めたため、今回の開発ではどのディレクトリにも属さず現行の制約に縛られることなくNode.jsのバージョンを上げることができました。 開発が落ち着いた現在では、バージョンを 20.12.2 にまで上げており、20.x系の最新版に対応しています。 Reactを17系から18系にアップデート ReactはNode.jsとは異なり、ビルド後のJavaScriptファイルがすべてグローバルにあるReactを参照してしまう課題がありました。 そのため、現在の管理画面では React や React DOM をCDNから呼び出すように変更しました。 これにより、 package.json 側のReactは自由にバージョンを変更できるようになりました。 この課題に関しては機能開発チームではなく別のチームに作業を依頼し、解決してもらいました! Storybookの8.xをalpha版から導入 Storybookを導入するタイミングで、既に 8.0.0-alpha.0 がリリースされていました。 v7の安定版を使用することも考えられましたが、UIコンポーネントを作成する段階であったことや、alpha版であっても最初からv8を導入してv8の仕様に合わせることで、よりスムーズに作業が進められると考えました。 開発が終了する頃には、v8が安定版になっている可能性も考慮しました。 ただし、8.0.0-alpha.6から次のバージョンにアップグレードする際に問題が発生し、一時期バージョンのアップグレードが停滞しました。 その際の原因は次の通りです。 github.com Stroybookのconfigにpluginとして明示的に @vitejs/plugin-react を記述する必要になってました。 import type { StorybookConfig } from '@storybook/react-vite' ; import { mergeConfig } from 'vite' ; import react from "@vitejs/plugin-react" ; import tsconfigPaths from 'vite-tsconfig-paths' ; const config: StorybookConfig = { /** ローカル環境でStorybookを起動するときに使用するViteの設定 */ async viteFinal ( config ) { return mergeConfig ( config , { /** ↓ここに`react()`が必要になった **/ plugins: [ react (), tsconfigPaths () ] , } ); } , docs: { autodocs: true , } , } ; export default config ; 解決後には 8.0.0-rc.2 までバージョンをアップグレードすることができ、その後は定期的に最新版にアップデート出来るようになりました。 現在はDependabotを使用して細かなアップデートを行っています。 StorybookのバージョンがあがるとAddOnのバージョンも上がるため、コマンドで一括で上げてます。 npx storybook@latest upgrade 開発が落ち着いた今では 8.0.9 まで上げてあります! Biome の導入 最初はESLintとPrettierを使っていたのですが、 ESLintとPrettierがともかく遅いからなんとかしたい!! というモチベーションで、すこしでも早くしようと思って導入しました。 LinterやFormatterは husky + lint-staged を使ってコミットのたびに発火するようにしています。 そのため、lintやformatが遅いとコミットのたびにその遅さに付き合わなければなりません。 CI/CDなど、頻繁に発生するプロセスの速度に関しては、このプロジェクトではかなり気にかけたところです。 最初はPrettierをやめてRust製の dprint に変えてみて、これだけでもPrettierより結構早くなったので結構満足してました。 その後にBiomeがメジャーバージョンが上がった事を知って、ESLintと置き換えるために検証したところ・・・ 13秒かかっていたLintが0.24秒になりました!! ESLintに戻ることが難しくなったためLinterはBiomeに移行し、dprintで設定できるフォーマットもBiomeが可能であるため、FormatterもdprintからBiomeに乗り換えました。 Biomeは開発が盛んなため、更新とルールの追加が頻繁に行われています。 なので バージョン上げたタイミングで新しいルールが追加されてLintで引っかかることはよくありました。 基本は全ルールをOnにしており、後から追加のルールや適用が難しいと思われるルールについてはoffにしてます。 ESLintのルールが充実してきたため、最近は少し落ち着いてきました! biomejs.dev importの並び替えや未使用importの自動削除など、機能も増えてきたのでオススメです! testing-liblraryの導入(v12)とアップデート(v15) 管理画面側には testing-liblrary がもともと入っていなかったため新しく導入することにしました。 v13以上はReact17非対応であったため最初はv12からしか入れられませんでしたが、Reactの課題を解決していただいたおかげでtesting-liblraryのバージョンも上げることができv14まで上げられました。 その後にv15へのメジャーアップデートが来たので、既に書いてあったテストを一通り流して特に問題がなかったのでそのままv15までアップデートしました。 まだ新規の範囲が小さいのでテストの量も少ないのもあって、そこまで苦戦することもなくアップデートできたのでよかったです。 やりきれなかったこと 完全な切り離しは今の管理画面の仕様では機能実装と並行で行うのは困難で、 Ruby on RailsにReactを乗せる形での開発 からは完全に抜けることはできなかったです。 そのためNext.jsも入れられませんでしたが、切り離しになった際にNext.jsにスムーズに移行できるような状態には出来たと思います。 また、切り離しのプロジェクトが検討してもらえるところまで持っていけたのは、新しいことの知見以外でチャレンジして得られた成果かなと思います! 最後に ここまで長々と書きましたが、最後まで読んでくださりありがとうございました。 今回やってみたいことを打診できたことや、自分のチームだけでなく垣根を超えて他チームに助けてもらったことが多々ありました。 その上でなりたったチャレンジだと思っているので、協力をしてくださった方々にはとても感謝してます! スタメンでは一緒に働いてくださるエンジニアを絶賛募集中です!! プロダクトに興味を持ってくださった方でも、技術に興味を持ってくださった方でも、ぜひ一度下のリンクを覗いてみてください! herp.careers
株式会社スタメンでiOSエンジニアをしている青木 ( @38Punkd )です。 スタメンは、2024年3月22日~24日の3日間、ベルサール渋谷ファーストにて開催される「 try! Swift Tokyo 2024 」に初めてスポンサーとして協賛し、ブース出展をしました。 今回はカンファレンスやブースの様子をご紹介できればと思います! try! Swift Tokyo 2024、2日目終了。最高のセッションをありがとうございました🥳明日はワークショップの開催です。try! Swift Tokyo 2024, Day 2 has ended. Thank you for the amazing sessions. Tomorrow we have workshops. #tryswift pic.twitter.com/lp9bUzu8gf — try! Swift Tokyo (@tryswiftconf) 2024年3月23日 try! Swift とは? try! Swift は、Swiftとその周辺技術に特化した、 世界規模のカンファレンス です。 毎年、日本を含む世界各地で開催され、世界中のSwiftに関わる開発者が集まり、最新の技術やベストプラクティスについて学び、交流する場となっています。 基調講演・技術セッション・ワークショップ・ハッカソン・スポンサーブースといった内容がベースになっています。 私の肌感ですが、英語話者が3~4割はいたのではと思う程、当日は多くの国籍の方が会場にいらっしゃいました。 ユニークなオープニングと共に始まる 『 SWIFT PUNK 』登場!! 昨年AppleがWWDCで空間コンピュータ Vision Pro を発表して以来、私は Vision Pro を生で見るのは初めてでした。 なのでその感動もありつつ、どこか見覚えのある見た目で現れた御三方を前に、会場は一挙に笑いに包まれました。 個人・企業スポンサー一覧発表の際には、スタメンのロゴをしっかり私のiPhoneに収めました。 スポンサーブース 展示されてあるSwift UIのコードから、プレビュー表示されるとどうなるかを実際にペンで書いて正解数を競うコンテンツや、抽選器を回して賞に応じて景品がいただけるなど、各社様皆、ブースを訪問した方が楽しめるコンテンツが盛りだくさんでした。 弊社社員も大はしゃぎでした。 (左)RevenueCatのぬいぐるみをゲットして喜ぶエンジニア (右)メルカリブースではしゃぐエンジニア スタメンもブース出展はこれまで何度か行なってきましたが、今回は、昨年10月に弊社アプリ 『TUNAG』 でリリースした新機能 『TUNAG ベネフィット』 をブースコンテンツに用いました。 この機能は、様々な企業様の商品をお得に購入できるクーポン券を弊社アプリ上で発行できる機能です。 この機能で抽選もできるようになっています。 ブースに遊びにくださった方には、弊社アプリを実際に触ってもらい、抽選も楽しんでいただきました。 技術セッション 1, 2日目がセッション、3日目がワークショップ形式でした。 TCA(The Composable Architecture) のメンテナーであるBrandonさん( @mbrandonw )、Stephenさん( @stephencelis )による、Swift 6.0から登場したマクロのテストの仕方や、 fastlane のリードメンテナーであるJoshさん( @joshdholtz )による、コード署名を楽しく理解する方法をはじめとする多くのセッションが開催されました。 iOS開発者ならおそらく誰もがご存知の方のセッションを生で聴けるのは、やはり会場でしか得られない経験の一つでした。 その中でも私個人として特に印象が大きかったセッションは、omochimetaruさん( @omochimetaru )の、『Swiftの型推論を学ぼう / Learning Swift's Type Inference』です。 speakerdeck.com 私は普段、iOSアプリ開発をしている中で、コードの可読性やコンパイル速度を向上させるために、型推論を適切に使うよう心がけていました。 しかし、その推論がどのような法則や仕組みによって実現されているのかはコンパイラレベルで調べた事がありませんでした。 そのため、omochimetaruさんの発表内容はどれも私にとって新しく、とても興味深かったです。 📣 try! Swift Tokyo 2024 Session Start 📣 "Swiftの型推論を学ぼう / Learning Swift's Type Inference" 🗣️ by @omochimetaru 👏 #tryswift pic.twitter.com/IfYC6vG9Mp — try! Swift Tokyo (@tryswiftconf) 2024年3月23日 最後に 国籍関係なく、他のエンジニアの方と英語でSwiftやiOS開発のお話ができたのは、またとない貴重な機会でした。 また初めて英語メインでブース対応をしたこともあり、慣れない部分も多かったですが、参加者の皆さんとてもお優しく、たくさん交流する事ができました。 世界の開発者の方々から知見と英気をいただいたので、これからもiOS開発を頑張っていこうと思います! 採用情報 スタメンでは、iOSエンジニアに限らず全技術領域で、プロダクトを成長させていくエキスパートを募集しています。 もし興味を持っていただけたら、下記からご応募ください! herp.careers
こんにちは、株式会社スタメンでiOSエンジニアをしている青木 ( @38Punkd )です。 弊社iOSアプリチームは、開発人数が増えるにつれて、 コンフリクト頻度が増える ことに悩まされていました。 またアプリの機能も増え、機能や画面間の依存関係が複雑になりつつあり、 開発生産性を下げる要因 になっていました。 今回この問題を解消するためにマルチモジュール化を行いましたので、その概要をご紹介できればと思います。 マルチモジュール化とは? アプリのコードを、複数の独立したモジュール(単位)に分割することを指し、アプリの開発や保守を楽にするための手法です。 マルチモジュール化を進めることで、大規模なアプリを複数の小さなモジュールに分割して、それぞれのモジュールで独立して開発・テスト・管理できます。 iOSの場合、後述する プロジェクトファイル の厄介な問題も解消できます。 プロジェクトファイルとは Appleの提供するOS上(iOS, macOS, watchOS, etc..)で動くアプリを開発する時に必要なメタデータが記述されたファイル( project.pbxproj )です。 ソースコードを統合開発環境Xcodeが自動生成したインデックスで紐づけて管理しています。 プロジェクトファイルのソースコード ファイルの追加・移動・削除時などに、このプロジェクトファイルに変更が加わります。 複数人で開発をしていると、ファイル操作を同じタイミングで行うことは良くあるかと思いますが、その際にプロジェクトファイルが、オートマージ不可能なコンフリクトを容易に起こしてしまいます。 自動生成されたメタデータのコンフリクト解消は、中々に辛いものがあります。 遂にマルチモジュール化に踏み切る iOSのマルチモジュール化では、アプリのソースコードを Embedded Framework ないしは Swift Package にしてモジュール化を行います。 今回私たちは、アプリのソースコードをほぼ全て、 Swift Package にしてモジュール化を行いました。 Swift Package は、Apple 標準のパッケージマネージャ Swift Package Manager と同じくして登場した、新しいパッケージの種類です。 Swift Package 内の個々のファイルに対しては、プロジェクトファイルによるインデックス管理下から外れるため、上述したプロジェクトファイルでのコンフリクト頻度が激減します。 私たちのチームでは昨年、パッケージマネージャを Carthage から Swift Package Manager に移行していました。 既にSwift Package Manager を導入済みの環境であれば、アプリのソースコードを Swift Package 化もしやすいと考えました。 マルチモジュール後の構成 レイヤー × 機能 で以下のようにモジュール分割をしました。 (実際にはユーティリティ等の小さめのモジュールもありますが、割愛しています) データベースや外部ライブラリに依存する実装と、アプリの機能を表現する実装は、関心事が違うので、 Data モジュールと Domains モジュールで分けました。 開発は基本的に機能単位で行うことが多いので、Domainsモジュールに存在する各機能は、疎結合でありたいです。 なので、 Module A , Module B , ... というように各機能をさらにモジュール化して分けました(サブモジュール化に相当します)。 よかったこと Swift Package によるマルチモジュール化を行ったことで、コンフリクト頻度が減ったことはもちろん、機能間の依存関係が単一方向になるよう矯正され、より 疎結合・高凝集なコード になりました。 また、既存のコードから関心の分離を行なっていく過程で、責務についての議論をチームで活発に行うことができ、ソースコードへの深い理解につながるという副次的な効果も得られました。 今後の展望 機能毎でモジュールを分けたことで、ビルド直後に、指定の機能にショートカットしてアクセスできる ミニアプリ を作れるようになります。 ビルドターゲットをこのミニアプリにすれば、機能が増えてもビルド速度を高速に保つことが可能です。 今後はミニアプリを各機能毎に作り、開発生産性をさらに高めていければと思います。 最後に try! Swift Tokyo 2024 に出展します! 弊社は、2024年3月22日~24日の3日間、ベルサール渋谷ファーストにて開催される 「 try! Swift Tokyo 2024 」 tryswift.jp に、ゴールドスポンサーとして協賛し、ブース出展を致します。 この3日間を通して、iOSエンジニアの皆様や、他の様々な技術分野の皆様とお会いできることを心よりお待ちしております!! 採用情報 スタメンでは、iOSエンジニアに限らず全技術領域で、プロダクトを成長させていくエキスパートを募集しています。 もし興味を持っていただけたら、下記からご応募ください! herp.careers
はじめに 初期設定 詳細設定 Slack連携とアラートの整備 CircleCIとの連携によるRelease Managementの活用 運用 今後について まとめ はじめに プラットフォーム部 SREチームのショウゴ( @shogo_452 )です。 最近、TUNAGの新たなエラー監視ツールとして「 Sentry 」を導入しました。 本記事では、Railsアプリケーションに対するSentryの導入事例について紹介します。 初期設定 まずは、 sentry-ruby と sentry-rails というGemをインストールします。 Sidekiqを使用している場合は、 sentry-sidekiq も必要です。 gem ' sentry-ruby ' gem ' sentry-rails ' gem ' sentry-sidekiq ' docs.sentry.io docs.sentry.io 次に設定ファイルです。 config/initializers/sentry.rb という設定ファイルを作成し、設定を行います。 この設定まで行えば、基本的なエラーの検知が可能となります。 Sentry .init do |config| config.enabled_environments = %w( production staging ) config.dsn = ' https://xxxxxxx.ingest.sentry.io/xxxxxxx ' config.breadcrumbs_logger = [ :sentry_logger , :active_support_logger , :monotonic_active_support_logger , :http_logger ] config.sample_rate = 1 config.traces_sample_rate = 0.1 config.send_default_pii = true config.environment = Rails .env config.include_local_variables = true end include_local_variables はローカル変数の値の情報を送ることができます、また、 traces_sample_rate はトランザクションのサンプリング率の設定オプションなのですが、 ドキュメント通りに「1」と設定するとサンプリング率100%となり、AWSのNATゲートウェイを使用している環境の場合は、外部通信の通信量が大幅に増え、通信コストが大きく増える可能性があるため注意が必要です。 詳細設定 任意のイベントを送りたい場合は、 capture_message を使用します。levelは、 :fatal , :error , :warning , :log , :info , :debug の6種類が使用できます。 Sentry .capture_message( " Message " , level : :error ) rescueしている箇所で例外の情報を送りたい場合は、 capture_exception を使用します。 begin # Process A rescue StandardError => e Sentry .capture_exception(e) # Process B end set_tags , set_user , set_context などを用いるとデバッグ時に有用な情報を送ることができます。 set_tags は、Sentryの標準のタグに加えてタグ付けをカスタマイズすることができます。 TUNAGでは複数台のステージングの識別のためにタグ付けをしたり、アラームの設定用にbooleanの値でタグ付けしています。 Sentry .set_tags( staging_no : ENV [ ' STAGING_NO ' ]&.to_i) if Rails .env.staging? set_user は、id, username, email, ip_addressの4種類の情報を送ることができ、影響を受けているユーザー数や傾向の分析に役立てれます。 Sentry .set_user( id : current_user.id) set_context は、任意の情報をkey, valueの形式で送ることができ、デバッグに必要になる情報を送る際に便利です。 Sentry .configure_scope do |scope| scope.set_context( ' user_details ' , { user_status : current_user.status, tenant_id : curernt_tenant.id } ) end Slack連携とアラートの整備 Sentryは、Slackとの連携可能でアラートの通知をSlackに送ることができます。 Issue発行のSlack通知例 TUNAGでは、主に下記の4つのアラートを設定しています。 Issueの発行 エラー件数の閾値超過 影響を受けているユーザー数の閾値超過 直近のリリースが原因のエラーの発生 閾値も Critical Conditions と Warning Conditions の2段階で設定できるため、緊急性の判断がしやすいのも特徴的です。 docs.sentry.io CircleCIとの連携によるRelease Managementの活用 Sentryは、CircleCIと連携させることができ、リリース単位でエラーをトラッキングすることができます。 docs.sentry.io 下記がCircleCIのconfigファイルの抜粋です。 jobs : notify-sentry-deploy : executor : deploy environment : SENTRY_ORG : OrganizationName SENTRY_PROJECT : Project Name SENTRY_ENVIRONMENT : Environment steps : - run : name : Create release and notify Sentry of deploy command : | curl -sL https://sentry.io/get-cli/ | bash sentry-cli releases new -p $SENTRY_PROJECT $CIRCLE_SHA1 sentry-cli releases set-commits $CIRCLE_SHA1 --commit "own-repo@$CIRCLE_SHA1" sentry-cli releases finalize $CIRCLE_SHA1 sentry-cli releases deploys $CIRCLE_SHA1 new -e $SENTRY_ENVIRONMENT workflows : deploy_ecs_production : jobs : - build_tunag_production_image : filters : branches : only : main - notify-sentry-deploy : filters : branches : only : main requires : - build_tunag_production_image CirlceCIの環境変数の CIRCLE_SHA1 を用いるようにし、checkoutの時間を省略するようにしました。 この設定により、下図のようにリリース単位でエラーの発生をトラッキングできるようになり、 最新のリリースが原因のエラーが発生した場合のアラートの設定もできるようになりました。 Releases画面の例 運用 運用を開始するにあたり、下記のドキュメントを整備しました。 ドキュメント①:Sentryの運用方針 導入背景 プロジェクトの切り方 Issueのステータスの説明 通知用のSlackチャットルームの命名規則 必須設定のアラート etc. ドキュメント②:プロジェクト個別のIssueのトリアージ手順 分担 新規発行されたIssueのトリアージ アラート対応 etc. また、週1回のSentryデーという日を設けて棚卸しを行うことを始めました。 トリアージ漏れのIssueの処理、Issueのマージ、アラートの閾値の見直しを行っています。 運用を始めたばかりなので、まだ上手く回っていないところもあるため、 今後の改善を模索しています。 今後について Sentryでできることが把握でき、運用方針をまとめることができたため、 今後はTUNAGのフロントエンドや他のプロダクトへの横展開を今後進めていきます。 また、まだまだ活用できていないSentryの機能があるため、それらを活用して効率が良く漏れの無いエラー監視ができる仕組み作りをしていきたいです。 まとめ 本記事では、Railsアプリケーションに対するSentryの導入事例について紹介しました。 最後に、スタメンではエンジニアを募集しています。興味をもっていただけましたら、ぜひ下記からご応募ください。 herp.careers
はじめに 事前の検証作業 MySQL 5.7 ⇒ 8.0の変更点の影響確認 1. 照合順序 2. 暗黙のソート 3. 予約語 アップグレード方法の検討 パラメータグループの作成 パフォーマンス確認 アップグレード済みのステージング環境の運用 k6とDatadogを用いた主要画面のパフォーマンス確認 実行計画の変化の確認 SQLの改善 本番アップグレード作業 振り返りと今後について まとめ はじめに プラットフォーム部 SREチームのショウゴ( @shogo_452 )です。 TUNAGのメインデータベースをAmazon Aurora MySQL v2(MySQL5.7互換)からv3(MySQL8.0互換)にアップグレードしたので、その検証内容などアップグレード完了に至るまでの過程を共有します。 事前の検証作業 MySQL 5.7 ⇒ 8.0の変更点の影響確認 まずは、MySQL 5.7(以下、5.7)からMySQL 8.0(以下、8.0)へのバージョンアップにおける変更点とその影響有無の調査を行いました。 1. 照合順序 照合順序は、文字の並び替えや比較のルールです。 文字コードutf8mb4の照合順序のデフォルトが、8.0でutf8mb4_general_ciからutf8mb4_0900_as_ciに変更になりました。 TUNAGでは、明示的にutf8mb4_general_ciを指定していたため、影響はありませんでした。 各文字セットにはデフォルト照合があります。 たとえば、utf8mb4 および latin1 のデフォルトの照合は、それぞれ utf8mb4_0900_ai_ci および latin1_swedish_ci です。 dev.mysql.com 2. 暗黙のソート 5.7では、GROUP BY句で暗黙的にソートが行われていましたが、8.0からはこの暗黙のソートがなくなったため、ORDER BY句を使う必要があります。 TUNAGでは暗黙のソートに依存している箇所はなかったため、影響はありませんでした。 以前は (MySQL 5.7 以下)、GROUP BY は特定の条件下で暗黙的にソートされていました。 MySQL 8.0 では発生しなくなったため、暗黙的ソートを抑制するために最後に ORDER BY NULL を指定する必要はなくなりました (前述のとおり)。 ただし、クエリー結果は以前の MySQL バージョンとは異なる場合があります。 特定のソート順序を生成するには、ORDER BY 句を指定します。 dev.mysql.com 3. 予約語 8.0では、 新たな予約語 が追加されましたが、 TUNAGで使用しているRailsでは、テーブル名とカラム名をバッククォートでエスケープしてくれるので影響はありませんでした。 dev.mysql.com アップグレード方法の検討 最終的に 「インプレースアップグレード」 を選択しました。 Blue/Greenデプロイ(以下、B/Gデプロイ)も1つの選択肢としてあったのですが、既存のクラスターパラメータグループで binlog_format=MIXED に事前に変更する必要があり、8.0用の新規作成するカスタムパラメータグループで binlog_format=MIXED と設定することとし、今回はB/Gデプロイの選択を見送りました。 パラメータグループの作成 次に8.0用のカスタムパラメータグループの作成です。 まずは、既存の5.7のカスタムパラメータグループのうち、デフォルトの値からカスタムされているパラメータの確認を行いました。 確認の際は、AWS CLIとjqコマンドを用いてデフォルトパラメータグループとカスタムパラメータグループの内容をjsonファイル化し、両ファイルの差分をdiffで確認しました。 この方法を取ることでカスタマイズをしている内容を漏れなく確認することができました。 $ aws rds describe-db-cluster-parameters --db-cluster-parameter-group-name default.aurora-mysql5.7 | jq . > default-cluster-mysql5.7.json $ aws rds describe-db-cluster-parameters --db-cluster-parameter-group-name aurora-cluster-mysql5.7 | jq . > production-cluster-mysql5.7.json $ git diff default-cluster-mysql5.7.json production-cluster-mysql5.7.json $ aws rds describe-db-parameters --db-parameter-group-name default.aurora-mysql5.7 | jq . > default-instance-mysql5.7.json $ aws rds describe-db-parameters --db-parameter-group-name stats-aurora-mysql | jq . > production-instance-mysql5.7.json $ git diff default.aurora-mysql5.7.json production-instance-mysql5.7.json パフォーマンス確認 アップグレード済みのステージング環境の運用 まずは、何台かのステージング環境を8.0にアップグレードした状態で、他のエンジニアメンバーに普段の開発で使ってもらう運用を2週間程度行いました。 これは、普段の開発の中で著しくパフォーマンスが遅くなる画面やAPIを見つけることを狙いました。 k6とDatadogを用いた主要画面のパフォーマンス確認 次に、コアな機能のAPIに対して、関連するレコード数が最多のケースでパフォーマンス確認を行いました。 負荷試験ツールのk6を用いて、検証条件のケースをk6のシナリオに記述、リクエストを実行し、SQLの実行時間や画面の描画時間などの確認をDatadogのAPMを用いて行いました。 この確認の結果、主要なAPIの一部で大幅なパフォーマンスの劣化が起きることが判明しました。 k6.io 実行計画の変化の確認 8.0へのバージョンアップでパフォーマンスが大幅に劣化したSQL(一部省略)が下記となります。 SELECT `table_a`.`id`, -- 省略 FROM `table_a` LEFT OUTER JOIN -- 省略 WHERE -- 省略 AND `table_a`.`id` IN ( SELECT `table_a`.`id` FROM `table_a` LEFT OUTER JOIN -- 省略 WHERE -- 省略 AND ( `table_a`.`id` IN ( SELECT -- 👈 サブクエリ1 `table_b`.`table_a_id` FROM `table_b` WHERE -- 条件1(省略) ) OR `table_a`.`id` IN ( SELECT -- 👈 サブクエリ2 `table_c`.`table_a_id` FROM `table_c` WHERE -- 条件2( 省略) ) OR `table_a`.`id` NOT IN ( SELECT -- 👈 サブクエリ3 `table_c`.`table_a_id` FROM `table_c` WHERE -- 条件3(省略) ) ) ) ORDER BY `table_a`.`id` DESC ; 5.7では、サブクエリ1, 2, 3の部分に対してEXISTS戦略による最適化が適用されていたのですが、 8.0にバージョンアップすると実体化を使用した最適化(materialization)が適用され、実行計画が変わることが分かりました。 サブクエリの最適化状況を確認する場合は、EXPLAIN後にSHOW WARNINGSステートメントで発行できる追加情報もしくはオプティマイザトレースを参照すると確認することができます。 EXPLAIN SELECT * FROM test_table; SHOW WARNINGS; dev.mysql.com SET optimizer_trace= ' enabled=on ' ; EXPLAIN SELECT * FROM test_table; SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; dev.mysql.com SQLの改善 パフォーマンス劣化の原因となったSQLについては、様々な対策方法を検討した結果、 最終的にEXISTS句とNOT EXISTS句を明示的に使用するように変更することで、5.7の実行計画を維持できるようになりました。 SELECT `table_a`.`id`, -- 省略 FROM `table_a` LEFT OUTER JOIN -- 省略 WHERE -- 省略 AND `table_a`.`id` IN ( SELECT `table_a`.`id` FROM `table_a` LEFT OUTER JOIN -- 省略 WHERE -- 省略 AND ( EXISTS ( SELECT 1 FROM `table_b` WHERE (`table_a`.`id` = `table_b`.`table_a_id`) AND -- 条件1(省略) ) OR EXISTS ( SELECT 1 FROM `table_c` WHERE (`table_a`.`id` = `table_c`.`table_a_id`) AND -- 条件2(省略) ) OR NOT EXISTS ( SELECT 1 FROM `table_c` WHERE (`table_a`.`id` = `table_c`.`table_a_id`) AND -- 条件3(省略) ) ) ) ORDER BY `table_a`.`id` DESC ; 本番アップグレード作業 本番のアップグレードは、上記のSQL改善を行った上で、ステージング環境で確認した手順で作業を行いました。 アップグレード作業と合わせてCA証明書の更新も行いました。CA証明書は、負荷影響も考慮して既存のrds-ca-2019と同じアルゴリズムが使用されているrds-ca-rsa2048-g1を選択しました。 振り返りと今後について 事前の検証を入念に行ったこともあり、無事に何事もなくバージョンアップ作業を終えることができました。 今回作成した8.0用のパラメーターグループで binlog_format=MIXED を設定したことにより、 今後はB/Gデプロイを利用することができるため、次回はB/Gデプロイを試そうと思っています。 また、メジャーバージョンアップの検証手順が今回確立でき、別のデータベースのAurora PostgreSQL 11.17 から Aurora PostgreSQL 15.4 へのアップグレード作業を控えていたため、 早速手順を流用し先日アップグレードを無事終えました。 まとめ 本記事では、Amazon Aurora MySQL v2(MySQL5.7互換)からv3(MySQL8.0互換)へのアップグレードについて、 検証内容などアップグレード完了に至るまでの過程を紹介しました。 最後に、スタメンではエンジニアを募集しています。興味をもっていただけましたら、ぜひ下記からご応募ください。 herp.careers
こんにちは、エンジニアの @natsuokawai です。 先日開催された Kaigi on Rails 2023 にて、スタメンとしてスポンサーブースを出展しておりました。 遊びに来てくれた皆さんありがとうございました! スタメンのブース その際 Ruby on Rails に関するクイズを出題していたので、本記事ではそれらの解説を簡単にしたいと思います。 問題1 以下のコードを Rails 6.1 以前で実行した時の結果は?(Task は ActiveRecord オブジェクト、id は integer 型のカラムとする) task1 = Task .create( title : " Task 1 " ) task2 = Task .create( title : " Task 2 " ) tasks = Task .where( id : task1.id).merge( Task .where( id : task1.id..task2.id)).pluck(& :title ) 選択肢: ["Task 1"] ["Task 2"] ["Task 1", "Task 2"] [] 解説 正解は 1. ["Task 1"] です! 弊社のサービス TUNAG(ツナグ)の Rails バージョンを 6.1 → 7.0 に上げる際に引っかかったので、今回問題にしてみました。 Rails 6.1 以前では、 relation1.merge(relation2) とした際、relation1 と 2 の条件が AND で結合されたり、relation2 の条件で上書きされたりと、一貫性のない仕様になっていました。 上記コードでは AND で結合されるため 、 tasks を取得する際に発行される SQL は SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = 1 AND "tasks"."id" BETWEEN 1 AND 2 となり、 Task 1 のみが取得されます。 ちなみに Rails 7.0 以降では常に relation2 の条件で上書きされるように変更されたので、 ["Task 1", "Task 2"] になります。 詳細: Deprecate inconsistent behavior that merging conditions on the same column by kamipo · Pull Request #39328 · rails/rails · GitHub バージョンを上げたときのブログ記事: TUNAG の Rails バージョンが 7.0 になりました - stmn tech blog 問題2 以下のアソシエーションを持つモデルにおいて、正しく動作しないものはどれか? class User < ApplicationRecord belongs_to :company end class Company < ApplicationRecord has_many :users validates :name , presence : true end 選択肢: 1. User.joins(:company).where(company: {name: 'stmn'}).count 2. User.preload(:company).where(company: {name: 'stmn'}).count 3. User.eager_load(:company).where(company: {name: 'stmn'}).count 4. User.includes(:company).where(company: {name: 'stmn'}).count 解説 正解は(正しく動作しないのは) 2. User.preload(:company).where(company: {name: 'stmn'}).count です! N+1 問題の解消でお世話になるメソッドたちについてのクイズでした。 こちらは基礎的な問題だったので、正解者も多かったですね。 実際にコードを実行してクエリを見てみるとわかりやすいですが、1、3、4 は companies を JOIN をしているため、 where メソッドにて companies の絞り込みを行うことができます。 preload は JOIN しないので、companies を参照しようとしてエラーになります。 includes は内部で preload と eager_load を呼び分けるメソッドです。上記のような companies の絞り込みクエリなどがない場合は preload と同じ挙動になります。 参考: activerecord/lib/active_record/relation.rb#L915 activerecord/lib/active_record/relation.rb#L735 問題3 下記のようなコントローラーが定義されているとき、コールバックに定義されたメソッドが実行される順番として正しいものはどれか? class ParentController < ApplicationController before_action :parent_before prepend_before_action :parent_prepend_before end class ChildController < ParentController before_action :child_before prepend_before_action :child_prepend_before end 選択肢: 1. parent_prepend_before → child_prepend_before → child_before → parent_before 2. parent_prepend_before → child_prepend_before → parent_before → child_before 3. child_prepend_before → parent_prepend_before → child_before → parent_before 4. child_prepend_before → parent_prepend_before → parent_before → child_before 解説 正解は 4. child_prepend_before → parent_prepend_before → parent_before → child_before です! コールバックの実行順序に関する問題です。レビューでこんなコードが来たら通さないよねと言われた回数第一位です (それはそう) 継承関係にあるとき、親→子の順でコールバックが実行されます。 また、 prepend_before_action は before_action の配列の先頭にメソッドを追加するので( Array#prepend と同じ)、今回のような場合は親が先に before_action の前に追加し、子がさらにその前に追加します。 参考: actionpack/lib/abstract_controller/callbacks.rb#L171-L175 activesupport/lib/active_support/callbacks.rb#L744 問題4 update! を実行したときのクエリの発行回数は Rails 7.0 以前と 7.1 でそれぞれ何回か?( Post.last で発行されるクエリは考慮しない) class User < ApplicationRecord has_many :posts end class Post < ApplicationRecord belongs_to :user end post = Post .last post.update!( title : " Rails is the best " ) 解説 正解は 「7.0 以前は 2 回、7.1 以降は 1 回」です! こちらもまた Rails バージョンによる差異の問題になります。 optional: true ではない belongs_to 関連が定義されているとき、Rails 7.0 以前は update! のタイミングで関連先のレコードをロードしていました。 7.1 以降では関連先に変更がなければロードしないようになり、クエリの発行回数が減っています。 詳細: Avoid validating `belongs_to` association if it has not changed by fatkodima · Pull Request #46522 · rails/rails · GitHub まとめ Kaigi on Railsのコアコンセプトは 「初学者から上級者までが楽しめるWeb系の技術カンファレンス」ということで、馴染みのあるメソッドを中心に選んでみました。 ブースではこのクイズを起点にして、Rails を始めたばかりの方やコミッターなど幅広い方と盛り上がることができ、とても楽しかったです。 最後に、スタメンではエンジニアを募集しています。Rails 好きな方はもちろん、フロントエンドやモバイルアプリなど各技術領域で募集中なので、ご応募お待ちしております! herp.careers