1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

現場で Ruby を書き続けて 6 年、失敗から学んだ「使い方」のリアル

1
Posted at

はじめに

Ruby を触り始めた頃、チュートリアルや書籍では「綺麗なコード」「テストファースト」「gem は便利」といった理想が並んでいました。しかし、実際のプロジェクトに入ってみると、依存関係の地獄、テストが書かれていないレガシーなコード、デプロイ時にだけ発生するエンコーディング問題など、教科書には載っていない「現場特有の癖」に毎日直面します。私も最初の半年は「自分にはまだ早い」と感じ、夜中にスタックオーバーフローを漁る日々でした。この記事では、そんな現場で何度も転びながら身につけた、Ruby を「使いこなす」ための具体的な習慣や判断基準を、少し先を歩く先輩として共有します。読み終わったときに「明日から試せることが一つでも増えた」と思ってもらえれば嬉しいです。

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

スイカゲームとにゃんこ大戦争のようなタワーディフェンス系ゲームを組み合わせたゲームを作成しました!
遊んでみていただけると嬉しいです🙇‍♂️


ハジメル.dev: https://hajimeru-dev.vercel.app/

「ひとりで続けるのは難しい」「何から学べばいいか分からない」という方向けに、
プログラミングのマンツーマンレッスンサービス「ハジメル.dev」も運営しています。
未経験OK・オンライン完結・月額制/違約金なしなので、気軽に無料相談してみてください🙇‍♂️


海外テックニュースを追いたいけど、英語や情報量の多さで大変…という方向けに、
Hacker News の話題を日本語でサクッと追える「HackerNews 日本語まとめ & AI要約」
を個人開発しました!
技術トレンド収集に使ってもらえると嬉しいです🔥🙇‍♂️
→ HackerNews 日本語まとめ & AI要約: https://hn-matome-2ht.pages.dev/


「ニャンパイアサバイバー」というヴァンパイアサバイバーリスペクトのゲームを作成しました!
もしよろしければ遊んで頂けると嬉しいです😭


習い事教室の先生向けに、SNS 投稿・生徒募集・保護者通知の文章を AI で生成する Web サービス「おしらせAI」を個人開発しました。Next.js + Supabase + LLM で構成しており、無料で月 10 回まで試用できます。よければ触ってみてください。

→ おしらせAI: https://oshirase-ai.vercel.app/

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

gem の選び方と依存地獄を避ける

プロジェクト立ち上げの最初の週、先輩から「まず Gemfile を整理しろ」と言われたとき、私は「gem を増やせば機能が増える」と思い込み、気軽に gem 'devise', gem 'cancancan', gem 'sidekiq', gem 'redis' などを追加しました。結果、bundle install に 5 分以上かかり、CI で依存解決エラーが頻発。さらに、ある gem が別の gem とバージョン競合を起こし、本番で LoadError が出る事態に。この経験から学んだのは、「gem は最小限にし、公式ドキュメントの『依存関係』セクションを必ず確認する」という原則です。具体的には、以下のチェックリストを毎回実行しています。

  1. 目的が明確か – その機能を自前で書けるなら gem を入れない。
  2. メンテナンス状況 – 最後のリリースが 1 年以上前なら避ける。
  3. 依存ツリーの深さbundle viz で可視化し、深すぎる場合は代替を探す。
  4. ライセンス – 商用利用で問題ないか確認。
# Gemfile 例:最小構成
source 'https://rubygems.org'

gem 'rails', '~> 7.1'
gem 'pg', '~> 1.5'
gem 'puma', '~> 6.4'
# 認証は自前で実装するため devise は入れない
gem 'sidekiq', '~> 7.2'   # 非同期ジョブが必要な場合のみ
gem 'redis', '~> 5.1', require: false

また、bundle outdated を週次で実行し、セキュリティパッチが出たら即座にアップデートする運用にしています。これにより「依存地獄」にハマる頻度が劇的に減り、新人メンバーが加わったときも bundle install が 30 秒以内で終わる環境を維持できています。

テストを書く習慣が現場を救う

「テストは書くもの」と頭では分かっていても、納期優先で後回しにしがちです。私が痛感したのは、あるリリース直前に User#full_namenil を返すバグを見逃し、本番でユーザー名が空白で表示された事件です。当時、モデルに対する単体テストがゼロだったため、リグレッションに気づく手段がありませんでした。それ以来、以下のルールを自分に課しています。

  • 新規機能には必ず RSpec の describe ブロックを一つ作る – 即使是最小の it 'returns full name' でも良い。
  • 既存コードを触る前には、そのメソッドをカバーするテストを先に書く – 「テスト駆動でリファクタ」のミニ版。
  • CI で bundle exec rspec --fail-fast を必須化 – 失敗したら即マージブロック。
# spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  describe '#full_name' do
    it 'returns concatenated first and last name' do
      user = build(:user, first_name: '太郎', last_name: '山田')
      expect(user.full_name).to eq '山田 太郎'
    end

    it 'handles missing first_name gracefully' do
      user = build(:user, first_name: nil, last_name: '山田')
      expect(user.full_name).to eq '山田'
    end
  end
end

この習慣のおかげで、リファクタリング時に「テストが通れば安心」という感覚が身につき、デグレードゼロのリリースを半年続けられています。テストコード自体もドキュメント代わりになり、新メンバーが仕様を把握するスピードが上がりました。

リファクタリングのタイミングを見極める

「綺麗なコードにしたい」という気持ちは大切ですが、現場では「今すぐ動くコード」が優先される場面が多々あります。私が失敗したのは、機能追加の合間に大規模なリファクタを入れようとし、ブランチが 2 週間もマージされず、他のメンバーがコンフリクトで苦労したことです。そこから学んだのは、「リファクタリングは『小さく、頻繁に、テストが緑の状態で』行う」という原則です。具体的な運用として以下を徹底しています。

  1. ボーイスカウトルール – ファイルを開いたら、その場で 1〜2 行の改善(命名の修正、不要なコメント削除、マジックナンバーの定数化)だけ行う。
  2. 専用ブランチで 1 時間以内に完了 – 大きな構造変更は Issue 化し、スプリントの最初に計画する。
  3. リファクタ前後に rubocop -abundle exec rspec を実行 – スタイル統一と回帰テストを自動化。
# リファクタ前
def calculate_total(items)
  total = 0
  items.each { |i| total += i.price * i.quantity }
  total
end

# リファクタ後(ボーイスカウトルール適用)
def calculate_total(items)
  items.sum { |item| item.price * item.quantity }
end

このように小さな改善を積み重ねると、半年後には「あの頃のスパゲッティコードがどこにあったか思い出せない」ほどクリーンなコードベースになります。また、レビュー時に「ここだけ直した」という小さな PR は承認が速く、チーム全体の心理的負担も減ります。

コードレビューで磨く「読みやすさ」

コードレビューは単なるバグ探しではなく、チーム全体の「読みやすさ」の基準を共有する場です。最初の頃、私は「動けば OK」と思い、変数名を x, tmp, data など適当につけていました。先輩から「この data が何を指しているか、1 ヶ月後に自分で読めるか?」と問われ、ハッとしました。それ以来、レビュー時に以下のポイントを意識してコメントし、自分も同じ基準で書くようにしています。

  • 意図が伝わる命名user_records ではなく active_userscalc ではなく calculate_monthly_fee
  • メソッドの単一責任 – 1 メソッド 10 行以内、引数 3 つ以内を目安に分割。
  • 早期リターンでネストを浅くreturn unless condition を活用し、if/else の深さを 2 段以内に。
# レビュー前(ネスト深い)
def charge(user, plan)
  if user.active?
    if plan.paid?
      if user.credit_card.present?
        PaymentGateway.charge(user.credit_card, plan.amount)
      else
        raise 'クレジットカードが登録されていません'
      end
    end
  end
end

# レビュー後(早期リターン+単一責任)
def charge(user, plan)
  return unless user.active?
  return unless plan.paid?
  raise 'クレジットカードが登録されていません' unless user.credit_card.present?

  PaymentGateway.charge(user.credit_card, plan.amount)
end

レビューでこの指摘を受けたとき、最初は「面倒だ」と思いましたが、実際にこのスタイルで書き直すと、後から自分が読み返したときに「何をしているコードか即座に理解できる」ことに気づきました。チーム内でこの基準が共有されると、新人でも 1 週間で「読みやすいコード」を書けるようになり、レビューの往復が減り、デプロイ頻度が上がりました。

デプロイ・運用で気をつけたい Ruby の癖

最後に、本番環境特有の Ruby の挙動でハマった経験を共有します。ある夜、デプロイ後に Encoding::CompatibilityError が大量に発生し、ログが文字化けして原因特定に 3 時間かかりました。原因は、開発環境が UTF-8 で統一されていたのに対し、本番の DB 接続設定で encoding: utf8mb4 が抜けていたこと、さらに config.encoding = 'utf-8'application.rb になかったことです。これを防ぐために、以下のチェックリストをデプロイ前の「リリース前チェック」として CI に組み込みました。

  • config.encoding = 'utf-8'config/application.rb にあるか。
  • database.ymlencoding: utf8mb4collation: utf8mb4_general_ci が全環境で設定されているか。
  • Bundle exec rails assets:precompile がエラーなく通るか(SassC のエンコーディング問題を早期検知)。
  • bundle exec sidekiq -C config/sidekiq.yml でジョブキューが正常に起動するか。
# config/database.yml(本番例)
production:
  <<: *default
  database: myapp_production
  username: <%= ENV['DB_USER'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  encoding: utf8mb4
  collation: utf8mb4_general_ci

また、Ruby の GC チューニング(RUBY_GC_HEAP_GROWTH_FACTOR など)も本番メモリ使用量を安定させるために設定しています。これらを自動化しておくことで、「深夜のデプロイでまたエンコーディングか」と慌てることがなくなり、安心してリリースできるようになりました。

まとめ

現場で Ruby を書き続ける中で、gem の選定、テスト習慣、リファクタリングの粒度、コードレビューの基準、デプロイ前のエンコーディングチェック――これら五つのポイントを意識するだけで、日々の開発ストレスが大きく減り、チーム全体の生産性が上がりました。完璧を目指す必要はなく、まずは一つずつ自分のワークフローに取り入れてみてください。明日からでも「ボーイスカウトルールで 1 行直す」「新機能に 1 テスト書く」といった小さなアクションから始めれば、半年後には確実に「現場で使える Ruby エンジニア」に近づいています。一緒にコツコツ積み上げていきましょう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?