Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
[Kaigi on Rais 2025] 全問正解率3%: RubyKaigiで出題したやり...
Search
Yuta Nakashima
September 26, 2025
Programming
850
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
[Kaigi on Rais 2025] 全問正解率3%: RubyKaigiで出題したやりがちな 危険コード5選
https://kaigionrails.org/2025/talks/power3812/#day1
Yuta Nakashima
September 26, 2025
Other Decks in Programming
See All in Programming
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
5
3.3k
AI活用は、個人から組織へ|マルチプレイヤーエージェントハーネス「QM」の社内活用事例 / AI use is moving from individuals to orgs
rkaga
1
110
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
130
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.8k
XHTMLが残したもの
yosuke_furukawa
PRO
2
810
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
330
iOSDC2026登壇資料.pdf
riofujimon
0
170
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
700
すこし踏み込む CancellationToken
htkym
1
380
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
250
新卒PdEのリアル
ryu1013
1
500
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
210
Featured
See All Featured
First, design no harm
axbom
PRO
2
1.3k
Mobile First: as difficult as doing things right
swwweet
225
10k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The World Runs on Bad Software
bkeepers
PRO
72
12k
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
65k
The Cost Of JavaScript in 2023
addyosmani
55
10k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
How to Think Like a Performance Engineer
csswizardry
28
2.8k
Transcript
全問正解率 3%: RubyKaigiで出題したやりがちな 危険コード 5選 Kaigi on Rails 2025, 2025.09.26
(Fri.)@JP TOWER Hall & Conference Hall Red Hubble,Inc Backend Tech Lead Yuta Nakashima
Yuta Nakashima Hubble,Inc Backend Tech Lead エンジニア歴 6年、Rails歴4年半 HubbleにCTO以来の一人目バックエンドエンジニアとして入 社
趣味: メタル/ラウド系のライブでよくモッシュしてます 自己紹介 2
ハブル AI契約業務・管理クラウド 契約書の作成、社内のやりとり、 検討過程や合意文書を一元管 理。 3
契約業務の オールインワンプラットフォーム 発生・起案 審査・交渉 押印申請・捺印 保管・管理 更新 4
RubyKaigi 2025 初参加 初スポンサー 初ブース出展 前提 5
ブースにてコード問題を出題 全5問で正解数に応じて豪華景品を配布 前提 6
結果、3日間で100名程度の方が参加 5問全問正解が 3名 3問以上正解が 約15名 回答しづらい環境ではありましたが、想像以上に 難問だった可能性 ...🤔 前提 7
もしかして Kaigi on Railsで内容・解答を話せば、 役立つのでは ...? → この発表になります! 前提 8
今回話すことは所謂、 教科書的な話 • Transactionの範囲 • 非同期処理発火のタイミング • エラーハンドリング • SQL側の責務と
Ruby側の責務の切り分け、テーブル設計 実際のプロダクトコード になると気づかずに書いてしまっていることや、レ ビューでも気づかないことが往々にしてある 本題 9
問題文 + 問題のあるコード (問題文) • バグ要因、パフォーマンス、セキュリティ観点で何箇所か直したほうが 良いところがあるので、どう修正すべきか (Hogeをtransaction外に出 す等)を個数と行数を含めて箇条書きで回答してください。 •
問題の都合上、 Modelバリデーションではなくて Controller側でバリ デーションしていること、 Controllerにビジネスロジックを書いているこ と、外部APIコールのレスポンス制御部分は対象外です 。 出題形式 10
Hubbleを模した ドキュメントアップロード APIが題 材 11
12
13
• アクセストークンからユーザを取得 • ユーザが取得できなければ、 401エラー 問題なさそう! 14
15
• バリデーションエラーの配列を作成し、エラーを格納 • 空配列でなければ、 400エラー 問題なさそう! 16
17
• ユーザの組織からフォルダを全て取ってきて folder_idと一 致するかを any?で評価 🤔 18
問題点1: SQLで全件取得 • 大量のオブジェクト生成 : N個のフォルダがある場合、 N個のActiveRecordオブジェクトがメモリ上に生成され る • メモリリーク
: 不要なデータが大量にメモリに保持され、 GCの負荷が増大 • ネットワーク帯域の無駄遣い : DBサーバと APIサーバ間の不要な通信量増大 (コネクションプール を占有して他 APIにも影響する可能性 ) • DBサーバの CPU負荷: 不要なデータ (id以外のカラム )をシリアライズして送信する処理コスト • レスポンス時間の劣化 : フォルダ数に比例してレスポンスが遅くなる (最悪計算量 O(N)) • スケーラビリティの欠如 : データ量増加に対して線形的にパフォーマンスが悪化 (エンタープライズだと、数万 - 数十万は全然有り得る話 ) 19
解決方法1: exists?でSQLで存在確認 • ActiveRecordからBooleanに: exists?の返り値がTrueClass or FalseClassの1オブジェクトだけになるので大幅削減 • ネットワーク帯域を圧迫しない :
DBサーバとAPIサーバ間の不要な通信量が最小 • DBサーバのCPU負荷が最小: 不要なカラムのデータを取得しない ◦ 発行クエリ ◦ 今回だと約8バイト、全件取得だと約200-500バイト(カラム数による)✕ 件数 • レスポンス時間とスケーラビリティ : フォルダ数に関係なくインデックス (今回であればidでprimary key)があればO(logN) SELECT 1 AS one FROM folders WHERE folders.id = 1 LIMIT 1 20
21
• ユーザの組織からドキュメントを全て取ってきてる • ドキュメントのリレーション先のドキュメント詳細を eachで取 得してる 🤔 22
問題点2: SQLクエリではなく、 Ruby側で計算 • 1 + N回のクエリ実行 : 1,000件のドキュメントがあれば 1,001回のクエリが発行される(初回の
documents取得 + 各documentごと のdocument_detail取得) • コネクションプール枯渇 : 大量の小さなクエリでデータベース接続が長時間占有され、他のリクエストが接続待ちになる可能性 (Railsは1リクエスト、 1コネクション ) • DBサーバCPU負荷: 同じような小さなクエリを大量に処理する非効率性と クエリパーシング の繰り返し ◦ クエリパーシング (字句解析)はSQL実行のおよそ 40%を占める ◦ 同一クエリでもパラメータが違えば別クエリとして扱われる ◦ キャッシュが効かずパーシングが繰り返される • ラウンドトリップ回数増大 : アプリケーションサーバと DBサーバ間の通信が N回発生し、ネットワークレイテンシが N倍に累積(一般に 同一リージョン通信は 0.5ms - 2.0ms、クエリ実行自体は 0.1ms - 2.0ms) 23
解決方法2: sumでSQLで計算 • 単一クエリ実行 : 1,001回 → 1回のクエリで処理完了 • SQL集約関数活用
: データベースエンジンの最適化された SUM処理を利用 • サーバCPU負荷軽減 : Ruby側での繰り返し処理が不要 • ネットワーク通信最小化 : 1回の通信で処理完了 (別解) organizationテーブルに total_filesizeカラムを持つ • ドキュメントとの分離 : ドキュメント数が増えても影響なし、計算量 OrganizationのO(logN) (別解) KVSキャッシュ + 更新時検証 • EC在庫管理等 によくあるパターン 24
25
26
問題点3: トランザクション内での外部 API実行 • 参照ロック長時間保持 : 外部キー制約により参照先テーブル( Organization)の行が外 部APIのresponseが終わるまで共有ロック状態 •
排他ロック待ち発生 : 同一Organization行の更新・削除操作が全てブロックされる • 問題切り分けが難化 : ロジックが問題なのか、外部 API障害なのかの切り分けが難しく なる 27
解決方法3: 外部API実行をトランザクション外に • 通常のTransactionと同じロック : 長時間参照先テーブルをロックしない • 問題切り分けが容易 : ロジックが問題なのか、外部
API障害なのかの切り 分けがわかりやすい 28
29
問題点4: トランザクション内での非同期処理発火 • Race Condition発生: Job実行タイミングによってはコミット前のデータにアクセスして 例外発生 • ロールバック時の不整合 :
トランザクションロールバック後も非同期ジョブがキューに残 存して不要実行 • 不整合データ生成 : ロールバックしているのに他モデルのデータを作ってしまう可能性 • エラー状態の不明確性 : トランザクション失敗とジョブ失敗の区別が困難 30
解決方法4: 非同期処理発火をトランザクション外に • DBの整合性: 未コミットデータアクセス問題の解消 • システム安定性の改善 : Race Conditionやデッドロックの回避
• エラー処理の明確化 : 問題の切り分けとデバッグ効率化 • 開発・保守性向上 : テスト容易性とコードの責務分離 31
32
より詳細なことは明日の 14:10からの発表で! 33
34
35
問題点5: StandardErrorで全例外を処理 • 内部実装詳細の漏洩 : 内部エラー時に DB構造、テーブル名、カラム名、ファイルパス、 環境変数等が露出 • SQLインジェクション
: DBエラーで内部クエリ構造が露出 • HTTPステータスコードの固定化 : 全てのエラーが 500番になり適切でない (この場合だ とバリデーションエラーも 500になる) • ユーザビリティ低下 : 技術的なエラーメッセージでユーザーが混乱 (ユーザーが次に何 をすべきかわからない ) • テスト品質低下 : エラー条件のテストが不十分になる 36
解決方法5: エラー分岐、ステータスコード整理 • 内部情報漏洩防止 : 技術的詳細を隠蔽し、攻撃者に有用な情報を提供しない • クライアント側エラー判別しやすさ : バリデーションエラー(
400)と外部サービスエラー( 502/504)の明確 な区別 • 具体的なエラーケース検証 : 各例外(TimeoutError、ServiceError等)を個別にテスト可能 37
まとめ • 意外とちゃんと 意識しないといけないポイントが多い ◦ Transactionの範囲 ◦ 非同期処理発火タイミング ◦ エラーハンドリング
◦ SQL側の責務と Ruby側の責務の切り分け、テーブル設計 • 知識的に知ってても プロダクトコード になると意識せずに書きがち • 特に最近の AIによるVibe Codingでは意識していきたいところ 38
最後に Hubbleでは様々な 技術的課題 (特にパフォーマンスチューニング )に 取り組んでいます! ドライブシステムの複雑な親子関係の Ruby計算をSQLに置き換え アプリケーションの権限管理を SQLでのBit演算で計算
AIエージェントの他機能への横展開 , and more… そういったことに興味のある方はぜひ ブースまで! 39