RailsモデルとActive Record基礎|業務ロジックの置き場所を理解してモデル肥大化を防ぐ設計(Service・Query Object)
生徒
「Railsのモデルに処理を書いていたら、だんだん長くなって読めなくなりました……」
先生
「それはモデル肥大化と呼ばれる状態ですね。Railsではよくある悩みです。」
生徒
「業務ロジックって、どこに書けばいいんですか?」
先生
「ServiceやQuery Objectを使うと、役割ごとに整理できますよ。」
1. 業務ロジックとは?Rails初心者が混乱しやすいポイント
業務ロジックとは、アプリの中で 「こういう条件のときは、こう処理する」 といったルールのことです。 例えば、注文が確定したら在庫を減らす、 会員ランクによって割引率を変える、 こうした判断の流れが業務ロジックです。
Rails初心者の多くは、 これらの処理をすべてモデルに書いてしまいます。 最初は問題ありませんが、 機能が増えるほどモデルが太っていきます。
2. モデル肥大化とは?なぜ問題になるのか
モデル肥大化とは、 1つのモデルに大量の処理が詰め込まれ、 何をしているクラスなのか分からなくなる状態です。
例えるなら、 台所・リビング・寝室がすべて 1つの部屋に詰め込まれた家のようなものです。 使えなくはありませんが、とても不便です。
コードも同じで、 読みにくく、修正しづらく、 バグが生まれやすくなります。
3. まずはモデルの役割を整理しよう
Railsのモデルの主な役割は、 データの保存や取得、 バリデーションなどの基本的な責務です。
「データそのものに近い処理」はモデルに、 「流れや判断が多い処理」は 別の場所に分ける意識が大切です。
class Order < ApplicationRecord
validates :total_price, presence: true
end
このようなシンプルな内容であれば、 モデルに書いても問題ありません。
4. Serviceオブジェクトとは?処理をまとめる専用クラス
Serviceオブジェクトは、 「1つの目的の処理」を担当するクラスです。 注文確定処理やメール送信処理など、 まとまりのある業務ロジックを切り出します。
これは、料理で言うと 「調理専門の人」に仕事を任せるイメージです。 モデルは材料管理に集中できます。
class OrderCompleteService
def initialize(order)
@order = order
end
def call
@order.update(status: "completed")
end
end
このように処理を分けることで、 コードの見通しが良くなります。
5. Query Objectとは?検索ロジックの整理役
Query Objectは、 複雑な検索条件をまとめるためのクラスです。 Active Recordのクエリが 長くなってきたときに活躍します。
例えるなら、 条件検索の「専門フィルター係」です。
class ActiveUsersQuery
def self.call
User.where(active: true)
end
end
モデルから検索ロジックを外すことで、 Userモデルがスッキリします。
6. ServiceとQuery Objectを使うと何が良いのか
処理の置き場所を分けることで、 コードの役割がはっきりします。 「何をするクラスなのか」が 名前を見るだけで分かるようになります。
また、テストもしやすくなり、 修正の影響範囲も小さくなります。 Railsアプリが成長しても、 破綻しにくい設計になります。
7. Rails初心者が意識したい設計の考え方
最初から完璧な設計を目指す必要はありません。 ただし、 「モデルが長くなってきたな」 と感じたら、 責務を分けるサインです。
ServiceやQuery Objectは、 モデル肥大化を防ぐための 心強い味方です。 RailsとActive Recordを学ぶ中で、 少しずつ取り入れていきましょう。