【Ruby】未経験でエンジニアになって感じたスクール学習と実務の違い
- 最終更新日: 2026年2月10日(火)
- 公開日: 2026年2月11日(水)
こんにちは。
デザイン・システム室の以後です。
私はプログラミングスクールを経て、未経験でエンジニアになりました。
未経験者向けのスクールではRubyはよくある言語の一つだと思います。
私もRubyをスクールで学んでから入社しました。
そんな私が入社してから実務に携わり始めて感じたことを共有します。
特に現在Rubyを学習されていて、これから未経験でエンジニアを目指している方の参考になればと思います。
前提としまして、私は4ヶ月間のスクールでRuby on Railsのポートフォリオ作成まで行えるスクールに通っていました。
スクールでは、主にRuby on RailsのMVCフレームワークを使ってアプリを作る学習をしていました。
基本的な構造や条件分岐の方法などは感覚的にわかりやすく、Railsの文法に慣れることやアプリ作成の流れを学ぶことにはとても適していると感じます。
ですが、実務ではアプリを「作って終わり」ではありません。
- 維持
- 管理
- 改修
これらを必要とします。
1番の違いは、完成がゴールではないということです。
未来を考えた設計をしなければならないということが、私が初めて実務を行う中で感じた未経験での学習時との違いです。
そのためにスクールで学んだ知識を前提として、スタンスを変える必要があると感じました。
FATコントローラーとは?
もちろんスクールと実務の違いはたくさんありますが、最初に感じたのはこの「FATコントローラー」の問題でした。
「FATコントローラー」とは、コントローラーに処理が集中しすぎて長く複雑になった状態を指します。
初学者がMVCで学ぶ段階では気づきにくい(私はそもそもFATコントローラーという概念すらスクール学習時には知りませんでした)ですが、実務においてコードが成長すると以下の問題が出ます。
- テストがしにくい
コントローラーはHTTPリクエスト・レスポンスを扱うため、テストを書くと複雑になりやすい。 - 再利用性が低い
同じ処理を別の箇所でも使いたくても、コントローラー内のコードでは呼び出せない。 - 変更に弱い
複数の処理が1箇所に混ざると、変更の影響範囲が大きくなる。
FATコントローラーの例
class OrdersController < ApplicationController
def create
# 注文作成
@order = Order.new(order_params.merge(user: current_user))
if @order.save
# 在庫を減らす
@order.items.each do |item|
Inventory.decrease(item)
end
# ポイント付与
RewardPoint.add_for_order(current_user, @order)
# メール送信
OrderMailer.confirmation_email(@order).deliver_later
# 外部API連携
ShippingService.create_shipment(@order)
# 成功時リダイレクト
redirect_to @order
else
# 失敗時は再表示
render :new
end
rescue StandardError => e
Rails.logger.error("注文作成に失敗しました: #{e.message}")
redirect_to new_order_path, alert: "注文処理中にエラーが発生しました"
end
private
def order_params
params.require(:order).permit(:address, items_attributes: [:product_id, :quantity])
end
end上記コードは上から順に追っていくには読みやすいものだと思います。ですが、
- 「注文作成」「在庫減少」「ポイント付与」「メール送信」「外部API連携」など、複数の処理が混ざっている
- コントローラーが長く、読むだけでも大変
幾つものifが重なったコードの中の1部分を改修したいとなった時、
if X
①
elsif xxx
②
elsif xxxx
③
elsif xxxxx
④
else xxxxxx
⑤
end上記のような分岐のコードが出来上がったとして、③だけ内容を変えたいとなった際にXを呼んでいる影響範囲が大きくなり改修難易度が格段にあがります。
また、1つのアクションでこれぐらいのボリュームになってしまいますが、これが1つのコントローラーにいくつも定義され、そのようなファイルが数十も格納された状態から、特定の動きを編集、修正することは容易ではありません。
ではどうすればいいのか。
サービスとは何か?
Railsでは「Service」という専用のフォルダを作って、コントローラーでもモデルでもない、ビジネスロジックをまとめる場所として使うことが多いです。
- コントローラーは「受け取る・返す」だけ
- モデルは「データの管理やバリデーション」だけ
- 複雑な処理や複数モデルをまたぐ操作はサービスにまとめる
サービスに切り出すことで、テストしやすく、メソッドの再利用が簡単になります。
モデル・サービス・コントローラーの使い分け
要するに、MVCのCに書きがちなものを、MとS(サービス)フォルダにも分けて書けるということです。
| 層 | 役割 | 書く内容の例 |
|---|---|---|
| コントローラー | リクエストを受け取ってレスポンスを返す | パラメータ取得、サービス呼び出し、レンダリング |
| モデル | データやそのルールを扱う | バリデーション、関連付け、単純な集計や計算 |
| サービス | ビジネスロジック、複数モデルをまたぐ処理 | 注文作成フロー、メール送信、外部API連携、トランザクション管理 |
FATコントローラーをモデルとサービスに切り分けた例
モデルに切り出す処理
class Order < ApplicationRecord
has_many :items
def decrease_inventory
items.each { |item| Inventory.decrease(item) }
end
endサービスに切り出す処理
class CreateOrderService
def initialize(user, order_params)
@user = user
@order_params = order_params
end
def call
ActiveRecord::Base.transaction do
order = Order.create!(@order_params.merge(user: @user))
order.decrease_inventory
RewardPointService.new(@user, order).apply_points
OrderMailer.confirmation_email(order).deliver_later
ShippingService.new(order).create_shipment
order
end
end
endコントローラーは呼ぶだけ
class OrdersController < ApplicationController
def create
@order = CreateOrderService.new(current_user, order_params).call
if @order
redirect_to @order
else
render :new, alert: "注文処理中にエラーが発生しました"
end
end
private
def order_params
params.require(:order).permit(:address, items_attributes: [:product_id, :quantity])
end
endどうでしょう。内容は同じですが、3つのファイルに分けて記述できました。
先ほど簡易的に書いたコードで言うと、①〜⑤それぞれを別のメソッドX1、X2、X3、X4、X5のように名前をつけてバラバラにして保存しておけば良いということです。
こうすることで、ロジックに変更があった際の影響範囲がわかりやすくなったりと、維持・管理性が上がります。
しかし、これは一概に細かくすればいいというわけでもなく、正解はありません。
企業ごと、プロジェクトごとにそれぞれにあった粒度での記述が求められます。
答えがない以上、私も何が最適かを考える力を鍛え続けていく必要があると感じています。
まとめ
- スクールと実務ではスタンスが違う
- MVCだけで完結する作り方は、初学者にとって学びやすく、RubyやRailsの理解に役立つ
- しかし、実務では維持・管理・改修を考えるとFATコントローラーは避けるべき
- モデルとサービスに責務を切り分けることで、テストしやすく、再利用性も高い、見通しの将来性の高いコードになる
- 答えがない問題である以上、思考力の鍛錬は続いていく
さいごに
現在デザイン・システム室では、新しいメンバーを募集しています。少しでも興味を持たれた方は、ぜひご応募ください✨💻
皆様からのご応募、心よりお待ちしております。