😄
Railsにおけるモジュール設計
プロジェクトが大きくなるにつれてコードの重複や責務の分散が課題になることがあります。それらを解決するためにモジュールを活用することは効果的です。
モジュールとは?
Rubyのモジュールは、名前空間の整理やコードの再利用を目的としたツールです。以下のように利用します。
module Payment
class StripeService
def process
# Stripeによる支払い処理
end
end
end
上記のように名前空間を整理しすることで役割が明確化し、複数のモデルやクラスで同じ処理を必要とする場合にモジュールを利用できます。
再利用可能なモジュールの設計
モジュールを使う際は単一責任の原則を守ることが重要です。一つのモジュールが複数の責務を持つとメンテナンスが難しくなります。
例: ユーザー通知をモジュール化
module Notifiable
def send_notification(message)
NotificationService.send(user: self, message: message)
end
end
class User < ApplicationRecord
include Notifiable
end
user = User.first
user.send_notification("こんにちは!")
ActiveSupport::Concernの活用
Concernを使うと、インスタンスメソッドとクラスメソッドを整理しやすくなります。
下記の例ではincludedブロックでスコープを定義し、クラスメソッドをclass_methodsで追加しています。
module Archivable
extend ActiveSupport::Concern
included do
scope :archived, -> { where(archived: true) }
end
def archive
update(archived: true)
end
class_methods do
def bulk_archive(ids)
where(id: ids).update_all(archived: true)
end
end
end
class Post < ApplicationRecord
include Archivable
end
Post.archived # アーカイブ済みの投稿を取得
Post.bulk_archive([1, 2, 3]) # 複数の投稿を一括アーカイブ
モジュール設計のアンチパターン
何でもモジュール化しすぎる
モジュールが増えすぎると責務が不明確になります。例えば、以下のような肥大化したモジュールは注意が必要です。
module UserHelper
def send_email
# メール送信処理
end
def calculate_age
# 年齢計算処理
end
def archive_user
# ユーザーアーカイブ処理
end
end
まとめ
- モジュールはコードの再利用や名前空間の整理に効果的
- 単一責任の原則を守り、必要に応じてActiveSupport::Concernを活用する
- モジュール設計では責務を明確化し、依存関係を最小限に抑えることが重要
Discussion