Skip to content

필사 모드: モダン Ruby & Rails 2026 — Ruby 3.4 / Rails 8 / Hotwire / Sorbet / Kamal 2 / Solid Queue 徹底ガイド

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

1章 · 2026年の Ruby/Rails — 「死んだ」と言った人へ

2026年の風景。友人が YC Demo Day で自分のスタートアップを自慢している。「3週間で MVP を作って公開し、最初の50万ドル売上を達成した」。スタックを聞かれた彼は少し恥ずかしそうに答える。「Rails」。隣のテーブルの Next.js フルスタックエンジニアが目を丸くする。「まだ?」

まだだ。そして2026年には、これまで以上に静かに、これまで以上に多くの場所で動いている。

2020年代初頭のインターネット言説は「Rails は死んだ」だった。2026年の現実はその逆 — **Rails は死んでいないし、むしろ最も静かに、最も多く働いているスタックの一つ**になっている。GitHub、Shopify、Stripe、Airbnb、Basecamp、HEY、GitLab、Square、Coinbase、クックパッド、メルカリ、カカオペイの一部、トスの一部。挙げていくとキリがない。

なぜ死んでいないか。三つのことが同時に起きた。

1. **Ruby 3.4(2024年12月)** — YJIT(Yet Another JIT)が本当に速くなり、`error_highlight` がデフォルトになってデバッグがずっと親切になった。

2. **Rails 8(2024年11月)** — 37signals が Redis 依存を切り離す「Solid 三兄弟」(Queue, Cache, Cable)を発表した。Postgres または SQLite 一つでジョブキュー、キャッシュ、WebSocket をすべて回せる。

3. **Kamal 2** — `kamal deploy` 一行で自前のサーバーに Docker でデプロイする。Heroku/Vercel/AWS Fargate に月数百〜数千ドルを払わなくてもいい時代になった。

その上に **Hotwire**(Turbo + Stimulus)がある — React のビルドパイプラインなしでもインタラクティブな UI を作れる。**Sorbet**(Stripe 製の漸進的型チェッカー)と **Tapioca**(RBI 自動生成器)が型を入れてくれる。**Mission Control** が Sidekiq なしでジョブを監視する。**Propshaft** が sprockets を置き換えた新しいアセットパイプラインで、**Action Notifier** が Rails 8 の新しい通知フレームワークだ。

この記事は2026年の Ruby/Rails フルスタックを一気に見る。1章から11章までは各パーツの解剖、12章から14章までは代替と生態系と「誰が選ぶべきか」を見る。最後まで読めば、次のサイドプロジェクトで Next.js+Vercel の代わりに Rails 8+Kamal を選んだときに後悔しないかへの答えが出るはずだ。

2章 · Ruby 3.4(2024.12) — YJIT 改善と error_highlight デフォルト化

Ruby 3.4 は2024年12月25日(毎年クリスマスが Ruby のメジャーリリース日だ)に出た。大きなヘッドラインは二つ。

YJIT — Ruby の JIT は本物だ

YJIT(Yet Another JIT)は Shopify が作ったメソッドベースの JIT コンパイラで、Ruby 3.1 で実験的に入り、3.2 で本番投入可能になり、3.3 で ARM64 対応とメモリ使用量を減らし、**3.4 でウォームアップ時間をさらに短縮した**。Shopify 自身のベンチマークによれば Rails ワークロードで平均 1.4x ~ 2x 速くなる。単純な算術ループのようなマイクロベンチではもっと極端な数字が出るが、本当の意味は Rails コントローラーアクションのような実ワークロードで測られる。

有効化は一行。

config/boot.rb または環境変数

config/boot.rb の先頭

require 'bootsnap/setup' if ENV['DISABLE_BOOTSNAP'].nil?

環境変数で

RUBY_YJIT_ENABLE=1 bundle exec rails server

またはコードで明示的に。

config/application.rb

require_relative "boot"

require "rails/all"

if defined?(RubyVM::YJIT.enable)

RubyVM::YJIT.enable

end

...

Rails 8 は production 環境で YJIT をデフォルトで有効化する(`config/environments/production.rb` で明示的に切らない限り)。YJIT 統計を見るには。

Rails console で

RubyVM::YJIT.runtime_stats

=> {compile_time_ns: ..., compiled_iseq_count: ..., ...}

error_highlight — デフォルトで親切になったエラーメッセージ

Ruby 3.1 で入った `error_highlight` gem が 3.4 でさらに洗練された。`NoMethodError` が起きたとき単に "undefined method `foo'" ではなく、**ソースコードのどの部分で起きたかをキャレット(`^`)で示してくれる**。

伝統的な Ruby 1.x ~ 2.x のエラーはこうだった。

NoMethodError: undefined method `name' for nil:NilClass

app/models/user.rb:42:in `display'

3.4 ではこう。

app/models/user.rb:42:in 'User#display':

puts "Hello, " + user.profile.name

^^^^^

NoMethodError: undefined method 'name' for nil

`user.profile` が nil だということが一目で分かる。Sentry / Honeybadger / Bugsnag のようなエラートラッキングサービスもこのキャレット情報をそのまま保存する。

その他の変更

- `it` ブロックパラメータが正式に入った — `[1,2,3].map { it * 2 }` のように単一パラメータブロックを短く書ける。

- `Range#step` が `Range` を返していたのが `Enumerator` を返すように変わった。

- `Prism` パーサーがデフォルトになった — Ruby 標準パーサーを置き換える新パーサーで、IDE/LSP ツールがずっと速くなる。

- ガベージコレクタのチューニング可能なオプションが増えた(MMTk 互換モード)。

3章 · Rails 8(2024.11) — Solid トリオで Redis 依存を切り離す

Rails 8 は2024年11月に出た。DHH のキーノートの一言がすべてを要約する。

> 「We're going Redis-free by default.」

数年間、Rails アプリの標準インフラはこうだった: **Postgres + Redis + Sidekiq**。Redis は Sidekiq ジョブキュー、Rails キャッシュ、Action Cable パブサブに同時に使われていた。Redis が死ねばジョブも死に、キャッシュも死に、WebSocket も死ぬ。小さなチームが Redis を運用するのは常にコストだった。

Rails 8 の答え: **Solid Queue, Solid Cache, Solid Cable**。三つともデータベース(Postgres/MySQL/SQLite)にデータを書き込む。Redis が消えると依存ツリーが大きく単純化する。

[従来の Rails 7] [Rails 8 デフォルト]

───────────────── ─────────────

Rails app Rails app

| |

├── Postgres (データ) └── Postgres

├── Redis (Sidekiq キュー) ├── solid_queue_* テーブル

├── Redis (キャッシュ) ├── solid_cache_entries テーブル

└── Redis (Action Cable) └── solid_cable_messages テーブル

Rails 8 の新規アプリはデフォルトで SQLite で Solid 三つを全部回すこともできる — 本当にシングルバイナリに近い単純さだ。小さなサイドプロジェクトなら EC2 t4g.small 一台に SQLite + Solid Queue + Solid Cache + Solid Cable + Kamal で十分。

Rails 8 新規アプリ作成。

gem install rails -v "~> 8.0"

rails new myapp

デフォルトで SQLite + Solid Queue + Solid Cache + Solid Cable + Propshaft + Importmap + Hotwire

Postgres を使うなら。

rails new myapp --database=postgresql

既存の Rails 7 アプリを 8 に上げる方法は別途ガイドが必要なくらいなのでここでは触れない — Rails Edge Guides の Upgrade Guide を参考にしてほしい。

4章 · Solid Queue — Redis 依存除去の意味

Sidekiq は10年以上 Rails ジョブキューの事実上の標準だった。Redis をバックエンドに使い、BRPOP でジョブを取得し、fork+threads モデルでワーカーを動かす。速くて堅牢だ。だが欠点は? **Redis が必要だ。**

Solid Queue は37signals が HEY と Basecamp で実際に使っていたジョブキューをオープンソース化したもの。Postgres/MySQL/SQLite にジョブテーブルを作り、FOR UPDATE SKIP LOCKED(または SQLite のトランザクション)でジョブを掴む。

インストールは簡単。

bundle add solid_queue

bin/rails solid_queue:install

bin/rails db:migrate

`config/queue.yml` でワーカーを設定する。

default: &default

dispatchers:

- polling_interval: 1

batch_size: 500

workers:

- queues: "*"

threads: 5

processes: 1

polling_interval: 0.1

development:

<<: *default

production:

<<: *default

workers:

- queues: [ critical, default ]

threads: 10

processes: 2

polling_interval: 0.1

- queues: [ low_priority ]

threads: 3

processes: 1

polling_interval: 1

ジョブクラスは ActiveJob の標準インターフェースをそのまま使う。

class WelcomeEmailJob < ApplicationJob

queue_as :default

def perform(user_id)

user = User.find(user_id)

UserMailer.welcome(user).deliver_now

end

end

どこからでも

WelcomeEmailJob.perform_later(user.id)

WelcomeEmailJob.set(wait: 1.hour).perform_later(user.id)

Sidekiq から Solid Queue に移行するときコード変更はほぼない(ActiveJob インターフェースを使っていれば)。ただし **性能特性が異なる** — Redis インメモリキューより Postgres ディスクキューは100倍遅いが、小さなアプリには十分。分単位で数十万件処理するメガワークロードならまだ Sidekiq + Redis が良い。だが **分単位で数千件未満** なら Solid Queue が運用の単純さで勝つ。

5章 · Solid Cache + Solid Cable

Solid Cache

37signals の HEY は毎日テラバイト級のキャッシュを使う。Redis インメモリでは RAM コストが爆発した。答え? **ディスクベースのキャッシュ**。SSD が速くなった2020年代では、ディスクキャッシュも十分速い。

config/cache.yml

production:

database: cache

store_options:

max_age: <%= 2.weeks.to_i %>

max_size: 256.megabytes

namespace: <%= Rails.env %>

使い方は通常の `Rails.cache` と同じ。

Rails.cache.fetch("expensive_query", expires_in: 1.hour) do

ExpensiveQuery.compute

end

HEY 基準ではキャッシュヒットレイテンシが平均 1-3ms 程度。Redis より遅いが、価格対容量がはるかに大きい。

Solid Cable

Action Cable が Redis パブサブに依存していた部分をデータベースに移したもの。メッセージを `solid_cable_messages` テーブルに書き、`LISTEN/NOTIFY`(Postgres)またはポーリング(SQLite/MySQL)で購読者に配信する。

config/cable.yml

production:

adapter: solid_cable

connects_to:

database:

writing: cable

polling_interval: 0.1.seconds

message_retention: 1.day

チャットメッセージを送るコントローラー。

class ChatMessagesController < ApplicationController

def create

message = @room.messages.create!(body: params[:body], user: current_user)

Solid Cable で他のユーザーにブロードキャスト

ChatChannel.broadcast_to(@room, render_to_string(partial: "messages/message", locals: { message: message }))

head :no_content

end

end

数百同時接続のチャットなら十分。**数万人以上** なら Redis アダプタ(AnyCable のような)や専用ソリューションが必要だ。

6章 · Hotwire(Turbo + Stimulus) — React なしのインタラクティブ

Hotwire は「HTML Over the Wire」の略。哲学はシンプル: **JSON でデータを送ってクライアントが React でレンダリングする代わりに、サーバーが HTML 断片を送ってクライアントが DOM に差し込む**。

三つのパーツでできている。

1. **Turbo Drive** — すべてのリンククリックとフォーム送信を fetch で奪い取り、応答 HTML の `<body>` だけを差し替える。SPA のようなページ遷移を無料で提供。

2. **Turbo Frames** — `<turbo-frame id="cart">` のようなコンテナでページの一部だけを更新する。

3. **Turbo Streams** — サーバーが「この要素を追加/置換/削除しろ」という命令を HTML 断片と一緒に送る。WebSocket や SSE でリアルタイム更新が可能。

Turbo Drive 例

<!-- app/views/posts/index.html.erb -->

<%= link_to "新しい投稿", new_post_path %>

このリンクをクリックすると Turbo が fetch で奪い取り、応答の `<body>` だけを差し替える。JavaScript を一行も書かずに SPA 感覚。

Turbo Frames 例

<!-- app/views/posts/show.html.erb -->

<%= render @post.comments %>

<%= link_to "コメントを追加", new_post_comment_path(@post) %>

<!-- app/views/comments/new.html.erb -->

<%= form_with model: [@post, @comment] do |f| %>

<%= f.text_area :body %>

<%= f.submit "投稿" %>

<% end %>

「コメントを追加」リンクをクリックすると `id="comments"` フレームの中だけでフォームがロードされる。ページ全体は変わらない。

Turbo Streams でリアルタイム更新

app/models/comment.rb

class Comment < ApplicationRecord

belongs_to :post

belongs_to :user

broadcasts_to ->(comment) { [comment.post, "comments"] }

end

<!-- app/views/posts/show.html.erb -->

<%= turbo_stream_from @post, "comments" %>

<%= render @post.comments %>

これである誰かがコメントを追加すると、同じページを見ている全ユーザーに WebSocket(Solid Cable)で新しいコメントが即座に追加される。React/Vue 一行も書かずに。

Stimulus — 軽量な JS コントローラー

本当に複雑なクライアント相互作用が必要なときだけ Stimulus を使う。

// app/javascript/controllers/counter_controller.js

export default class extends Controller {

static targets = ["display"]

initialize() { this.count = 0 }

increment() {

this.count += 1

this.displayTarget.textContent = this.count

}

}

HTML が常に真実の源だ。React の「仮想 DOM が真実で実 DOM はそこから派生」とは正反対の哲学。

7章 · Sorbet(Stripe) + Tapioca — 漸進的型付け

Ruby は動的言語だ。変数に型がない。これは長所であり短所でもある。Stripe はコードベースが数百万行に成長して動的型付けの限界を痛感し、**Sorbet** を作った(2019年オープンソース化)。

Sorbet は Ruby に漸進的型付けを乗せる。すべてのファイルに一行追加する。

typed: true

require "sorbet-runtime"

class User

extend T::Sig

sig { params(name: String, age: Integer).returns(User) }

def self.create(name:, age:)

new(name: name, age: age)

end

sig { params(name: String, age: Integer).void }

def initialize(name:, age:)

@name = name

@age = age

end

sig { returns(String) }

def display

"#{@name} (#{@age})"

end

end

`# typed: true` は strict 度合いを意味する(`ignore` / `false` / `true` / `strict` / `strong`)。`sig { ... }` でメソッドシグネチャを宣言する。実行時には sorbet-runtime が引数の型を検証してエラーを投げ、静的解析では `srb tc` で型チェックを回す。

bundle add sorbet

bundle add sorbet-runtime

bundle exec srb init

bundle exec srb tc

Tapioca — Sorbet の自動 RBI 生成器

Sorbet は `.rbi` ファイル(RBI = Ruby Interface)から型シグネチャを読む。外部 gem に対するシグネチャを直接書くのは地獄 — **Tapioca** が自動生成する。

bundle add tapioca --group=development

bundle exec tapioca init

bundle exec tapioca gems # 全 gem の RBI 生成

bundle exec tapioca dsl # Rails DSL(スコープ、アソシエーション、アトリビュート)の RBI 生成

Tapioca DSL が作った RBI の例。

sorbet/rbi/dsl/user.rbi(自動生成)

class User

sig { returns(T.nilable(String)) }

def email; end

sig { params(value: T.nilable(String)).returns(T.nilable(String)) }

def email=(value); end

ActiveRecord スコープ

sig { returns(ActiveRecord::Relation) }

def self.active; end

end

これで IDE で `user.emil` のようなタイポも捕まる。Stripe 社内ではコードの80%以上が `# typed: true` 以上だという。

8章 · Kamal 2(37signals) — `kamal deploy` で直接デプロイ

37signals の DHH は2023年に「We have left the cloud」という記事で有名になった。Basecamp/HEY を AWS から自前データセンターに移して年700万ドルを節約したという記事だ。その移行過程で作ったツールが Kamal(元の名前は MRSK)。

Kamal 2(2024年リリース)は **Docker + SSH + 一行のコマンド** で任意の Linux サーバーにアプリをデプロイする。Heroku/Vercel/AWS Fargate なしで。

gem install kamal

kamal init

`config/deploy.yml` でデプロイを定義する。

service: myapp

image: myteam/myapp

servers:

web:

hosts:

- 1.2.3.4

- 1.2.3.5

job:

hosts:

- 1.2.3.6

cmd: bin/jobs

registry:

server: ghcr.io

username: myteam

password:

- KAMAL_REGISTRY_PASSWORD

env:

clear:

RAILS_ENV: production

RAILS_LOG_TO_STDOUT: 1

secret:

- RAILS_MASTER_KEY

- DATABASE_URL

accessories:

postgres:

image: postgres:16

hosts:

- 1.2.3.4

env:

secret:

- POSTGRES_PASSWORD

volumes:

- /var/lib/postgresql/data:/var/lib/postgresql/data

proxy:

ssl: true

host: myapp.com

デプロイは一行。

kamal deploy

何をしているか。

1. ローカルで Docker イメージビルド(または GitHub Actions でビルドしたものを pull)。

2. レジストリに push。

3. 全サーバーに SSH で入り、新しいイメージを pull。

4. 新しいコンテナを起動し、Kamal Proxy(Traefik 後継)がトラフィックを差し替える無停止デプロイ。

5. 古いコンテナをクリーンアップ。

初回デプロイ時は `kamal setup` を呼ぶと Docker インストールから全部やってくれる。

kamal setup # Docker インストール + 初期デプロイ

kamal deploy # 以降のデプロイ毎回

kamal rollback # ロールバック

kamal logs # ログ閲覧

kamal app exec --interactive --reuse "bin/rails console" # console 接続

EC2 t4g.medium 一台(月30ドル)に Postgres + Solid Queue + Rails アプリを全部立てれば、**Heroku hobby tier(月25ドル)に近い価格ではるかに強力なインスタンス** になる。トラフィックが増えればサーバーを増やして `kamal deploy --hosts ...` で水平スケール。

9章 · Mission Control — Rails ネイティブのジョブ監視

Sidekiq には常に良い Web UI(`/sidekiq`)があった。Solid Queue に移ったらこれを失うのか? いや — Rails 8 は **Mission Control - Jobs** という公式 Web UI を提供する。

bundle add mission_control-jobs

config/routes.rb

Rails.application.routes.draw do

mount MissionControl::Jobs::Engine, at: "/jobs"

...

end

config/application.rb

config.mission_control.jobs.base_controller_class = "AdminController" # 認証

`/jobs` に接続するとキュー状態、進行中ジョブ、失敗ジョブ、リトライ、ジョブ一時停止/再開がすべてできる。Sidekiq Web UI のほぼ全機能を提供しつつ、Solid Queue の全アダプタ(Postgres/MySQL/SQLite)で動作する。

加えてジョブ監視に良いツール。

- **Skylight** / **Scout APM** — ジョブのメモリ/CPU プロファイリング。

- **Sentry** / **Honeybadger** — ジョブ失敗時のエラー追跡とアラート。

- **Datadog** — Solid Queue テーブルメトリクスを直接収集。

10章 · Propshaft / Action Notifier — Rails 8 の新しい基本

Propshaft — sprockets の後継

Sprockets は Rails 2 からあったアセットパイプラインだ。CoffeeScript、Sass、ERB で JavaScript と CSS をコンパイルし、ダイジェストフィンガープリントを付けてキャッシュする。だが2020年代には esbuild、Vite、Bun、importmap-rails のようなツールがトランスパイルをもっとうまくやる。**Propshaft はトランスパイルしない** — ファイルにダイジェストフィンガープリントだけ付けて配信する。

Gemfile

gem "propshaft"

ダイジェストが付いたファイルを生成

bin/rails assets:precompile

新しいアセットパイプライン哲学。

- **トランスパイルは esbuild/Vite/jsbundling-rails の仕事。**

- **バンドリングもそれらの仕事。**

- **Propshaft は単純にダイジェストフィンガープリントと配信だけ。**

Rails 8 の新規アプリはデフォルトで **Propshaft + Importmap-rails + Hotwire** を使う。JavaScript は importmap でブラウザがネイティブに取得し、CSS は propshaft がフィンガープリントする。

Action Notifier(Rails 8 新規追加)

Rails 8 には通知(notification)システムが正式に入った。メール、SMS、プッシュ、Slack、データベースなど複数チャネルに同時に通知を送る標準抽象化だ。

class NewCommentNotifier < ApplicationNotifier

deliver_by :email, mailer: "CommentMailer", method: "new_comment"

deliver_by :slack, channel: "#engineering"

deliver_by :database

param :comment, :user

def message

"#{params[:user].name}が新しいコメントを投稿しました。"

end

end

呼び出し

NewCommentNotifier.with(comment: @comment, user: current_user).deliver(@post.author)

複数チャネルに同じメッセージを送る一般的なパターンを一箇所にまとめる。Noticed gem が着想元で、Rails 8 で公式化された。

11章 · RuboCop / Standard / Brakeman — 静的解析

RuboCop — 最も使われているリンター

RuboCop は Ruby の ESLint 的な存在。スタイル違反から潜在バグまで捕まえる。

bundle add rubocop --group=development

bundle exec rubocop

bundle exec rubocop -a # 自動修正

`rubocop-rails`、`rubocop-rspec`、`rubocop-performance` のような拡張 gem で範囲を広げる。

.rubocop.yml

require:

- rubocop-rails

- rubocop-rspec

- rubocop-performance

AllCops:

TargetRubyVersion: 3.4

TargetRailsVersion: 8.0

NewCops: enable

Style/StringLiterals:

EnforcedStyle: double_quotes

Layout/LineLength:

Max: 120

Standard — 意見のない RuboCop ラッパー

毎回 `.rubocop.yml` を決めるのが疲れるなら **Standard** を使おう。RuboCop をラップしつつ「もう全部決めたから黙ってろ」という哲学。

bundle add standard --group=development

bundle exec standardrb

bundle exec standardrb --fix

Tenderlove(Aaron Patterson)や多くの OSS メンテナが使っている。Prettier が JS でやったことを Ruby でやる。

Brakeman — 静的セキュリティ解析

Brakeman は Rails 専用の静的セキュリティ解析ツール。SQL インジェクション、mass assignment、XSS、コマンドインジェクションのような一般的な脆弱性を捕まえる。

bundle add brakeman --group=development

bundle exec brakeman

CI パイプラインに入れて PR ごとに回すと良い。GitHub Actions の例。

name: Brakeman

on: [pull_request]

jobs:

brakeman:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

- uses: ruby/setup-ruby@v1

with:

ruby-version: 3.4

bundler-cache: true

- run: bundle exec brakeman --no-pager

Rails 8 の新規アプリはデフォルトで RuboCop、Brakeman、そして GitHub Actions ワークフローを一緒に作ってくれる。

12章 · 代替 — Hanami 2 / Roda / Sinatra / dry-rb

Rails が全ての答えではない。Ruby 生態系には他に良い選択肢がある。

Hanami 2

Hanami は「Rails よりも明示的でモジュール化されたフレームワーク」を目指す。2022年に Hanami 2 が出てから本格的にプロダクション利用できるレベルになった。特徴。

- **依存性注入(DI)** コンテナが第一級市民。dry-system の上に作られている。

- ルーター / コントローラー(アクション) / ビュー / ビューモデルが明示的に分離。

- 「慣習より明示的」哲学。マジックが少ない。

slices/main/actions/books/index.rb

module Main

module Actions

module Books

class Index < Main::Action

include Deps[

"repositories.book_repo"

]

def handle(_request, response)

response[:books] = book_repo.all

end

end

end

end

end

小〜中規模の API/SaaS に適している。Rails より学習曲線は急だが、大きなコードベースで明示的な構造が価値を持つときに輝く。

Roda

Jeremy Evans(Sequel 作者)が作ったマイクロルーティングツリーベースのフレームワーク。非常に高速で、ツリールーティングでルートが自然にネストする。

require "roda"

class App < Roda

plugin :json

plugin :halt

route do |r|

r.root { { hello: "world" } }

r.on "users" do

r.get Integer do |id|

{ user_id: id }

end

r.post do

新規ユーザー

end

end

end

end

Sinatra より速く、Hanami より軽量。Shrine、Sequel のようなライブラリと相性が良い。

Sinatra

最も古いマイクロフレームワーク。シンプルな API や小さなツールには今でも良い。

require "sinatra"

get "/hello/:name" do

"Hello, #{params[:name]}"

end

dry-rb / Rom-rb

dry-rb は Hanami が基盤としているライブラリコレクション。`dry-validation`(スキーマ検証)、`dry-monads`(Result/Maybe モナド)、`dry-types`(型)、`dry-system`(DI コンテナ)、`dry-effects`(エフェクト)。Rails と一緒にも使える。

Rom-rb はデータマッパーパターンの ORM。ActiveRecord と違ってドメインオブジェクトと永続性を分離する。DDD を真面目にやるチームに魅力的。

13章 · 韓国 / 日本の Ruby 生態系 — クックパッド、メルカリ、カカオペイ

日本 — Ruby の本場

Ruby は Matz(まつもとゆきひろ)が1995年に作った。日本は Ruby の本場で、日本企業の Ruby/Rails 利用が最も深く長い。

- **クックパッド** — 日本最大のレシピサイト。ほぼ全てのバックエンドが Rails。RubyKaigi のメインスポンサー。Ruby/Rails カンファレンスの発表で社内モノリスをどう運用しているかをよく共有している。

- **メルカリ** — 日本最大のフリマアプリ。バックエンドの大部分が Ruby/Rails で、他は Go/Python に移行中。Go に移す部分も Ruby で始まったビジネスロジックを少しずつマイグレーションする。

- **GMO ペパボ** — ライブコマース/EC。

- **マネーフォワード** — 家計簿/会計 SaaS。Rails で始まり成長したケース。

- **Sansan** — 名刺管理。Rails ベース。

- **freee** — 会計 SaaS。Rails で IPO まで到達した。

日本では毎年 RubyKaigi(2-3日のカンファレンス)が開かれ、Matz が直接キーノートをする。Rails より Ruby 自体に関する発表が多く、MRI/YJIT/言語デザインの深い議論が日常だ。

韓国 — Rails 利用は増えている

韓国の Rails 利用は日本ほど大きくはないが、着実に増えている。

- **カカオペイ** — 一部のバックエンドが Rails。決済/メンバーシップ関連の一部ドメイン。

- **トス** — 一部の社内ツールと社内システムが Rails。

- **Bridge Plus / D.CAMP** — スタートアップアクセラレータがよく Rails で開始するスタートアップを見る。

- **よく知られた韓国の Rails 事例** — Class101、Mirinae、Zigbang の一部バックオフィスなど。

韓国は2010年代中盤に RubyKR カンファレンスが活発で、最近は RubyKR Slack/Discord コミュニティが小さいながら活発。韓国での Rails 開発者採用は日本ほどではないが着実にある(特にシニア/スタートアップテックリードポジションで)。

グローバル — よく知られた事例

- **Shopify** — 世界最大の Rails アプリ。YJIT の主要スポンサー。Rails コアへの多数のコントリビューション。

- **GitHub** — Rails で始まり今も大部分が Rails。モノリス運用の模範例。

- **Stripe** — Sorbet の発祥地。決済処理バックエンドの大部分が Ruby。

- **Airbnb** — 初期から Rails。一部は Java/Kotlin に移行、一部はまだ Ruby。

- **Basecamp / HEY** — 37signals 自社プロダクト。DHH のビジョンがそのまま具現化された場所。

- **GitLab** — Rails。セルフホストと SaaS 両方。

- **Twitch** — 初期 Rails、一部は Go/Erlang に移行。

- **Coinbase** — Rails で開始、一部は Go に移行。

14章 · 誰が Ruby/Rails を選ぶべきか — 1-2人 / スタートアップ / B2B SaaS

1-2人 / サイドプロジェクト

**圧倒的に Rails を推奨する。** 理由。

- **速度** — `rails new` 一行で認証、ジョブキュー、キャッシュ、WebSocket、マイグレーション、テスト、管理画面までセットアップされる。

- **インフラの単純さ** — Rails 8 + Solid トリオ + SQLite で EC2 t4g.small 一台に全部立てられる。

- **Kamal でデプロイコストがほぼ0** — Heroku/Vercel なしで月5ドルから始められる。

- **Hotwire でフロントエンドビルドパイプラインなし** — Node 依存ゼロ。

Next.js + Vercel + Postgres + Upstash Redis + Resend + Stripe で組むより、Rails + Kamal + Postgres 一つで組む方が速くて安い。

初期スタートアップ(1-15人)

**Rails はまだ最良の選択。** 37signals、GitHub、Stripe、Shopify が全部 Rails で始まり IPO/ユニコーンまで到達した。PMF を探す段階ではフルスタックフレームワークの凝集力が絶対的だ。Next.js のモノレポ + RPC + 認証ライブラリ + ジョブキュー依存ツリーは PMF 段階では荷物。

良い組み合わせ。

- Rails 8 + Postgres + Solid トリオ + Hotwire + Kamal 2。

- Sentry でエラー追跡、Skylight または Scout APM で APM。

- RSpec または Minitest、FactoryBot、Capybara/Cuprite でテスト。

- 漸進的に Sorbet 導入(最初から全部 strict にせず、コアドメインから)。

B2B SaaS(15-100人)

依然 Rails が良い。ただし **型とドメイン分離** にもっと気を配ろう。

- Sorbet でコアドメインの型を整える。

- Service Object / Command パターンで fat controller を避ける。

- Trailblazer、dry-rb、Hanami のパターンを部分的に導入。

- モノリスを維持しつつ Engine でドメインを分離(Shopify の「Modular Monolith」パターン)。

100人以上 / マイクロサービス段階

Rails もよく動くが、この時点では言語選択より **組織設計** がもっと重要になる。Rails モノリスが自然に分解されるなら、一部のサービスを Go/Java/Kotlin に移すことを検討する価値がある(Shopify がコアは Rails、一部のインフラ系サービスを Go/Rust に移行したように)。

Rails を避けるべき場合

- **超低レイテンシ(`<10ms`)がビジネスの中核** な場合 — ゲームサーバー、高頻度取引、組み込み。Go、Rust、Elixir、C++ が良い。

- **機械学習推論/学習パイプラインが本業** の場合 — Python が答え。

- **型が絶対的に必須** なドメイン — Sorbet である程度解決するが、最初から TypeScript/Kotlin/Rust の方が直線的な経路。

- **既に Node/Python 単一言語ポリシー** の会社 — わざわざ Ruby を追加する理由がない。

15章 · 参考 / References

- Ruby 3.4 Release Notes: https://www.ruby-lang.org/en/news/2024/12/25/ruby-3-4-0-released/

- Rails 8 Release Notes: https://rubyonrails.org/2024/11/8/rails-8-no-paas-required

- Rails Edge Guides: https://edgeguides.rubyonrails.org/

- YJIT Documentation: https://github.com/ruby/ruby/blob/master/doc/yjit/yjit.md

- Solid Queue: https://github.com/rails/solid_queue

- Solid Cache: https://github.com/rails/solid_cache

- Solid Cable: https://github.com/rails/solid_cable

- Hotwire: https://hotwired.dev/

- Turbo Handbook: https://turbo.hotwired.dev/handbook/introduction

- Stimulus Handbook: https://stimulus.hotwired.dev/handbook/introduction

- Sorbet: https://sorbet.org/

- Tapioca: https://github.com/Shopify/tapioca

- Kamal: https://kamal-deploy.org/

- Mission Control Jobs: https://github.com/rails/mission_control-jobs

- Propshaft: https://github.com/rails/propshaft

- RuboCop: https://docs.rubocop.org/rubocop/

- Standard Ruby: https://github.com/standardrb/standard

- Brakeman: https://brakemanscanner.org/

- Hanami: https://hanamirb.org/

- Roda: https://roda.jeremyevans.net/

- Sinatra: https://sinatrarb.com/

- dry-rb: https://dry-rb.org/

- Rom-rb: https://rom-rb.org/

- 37signals "Leaving the Cloud": https://world.hey.com/dhh/we-have-left-the-cloud-251760fb

- Cookpad Tech Blog: https://techlife.cookpad.com/

- Mercari Engineering Blog: https://engineering.mercari.com/en/

- RubyKaigi: https://rubykaigi.org/

- Shopify Engineering on YJIT: https://shopify.engineering/yjit-just-in-time-compiler-for-ruby

- GitHub on Modular Monoliths: https://github.blog/2022-08-03-monoliths-and-microservices/

현재 단락 (1/442)

2026年の風景。友人が YC Demo Day で自分のスタートアップを自慢している。「3週間で MVP を作って公開し、最初の50万ドル売上を達成した」。スタックを聞かれた彼は少し恥ずかしそうに答...

작성 글자: 0원문 글자: 18,910작성 단락: 0/442