This article shows how to reafactor common methods across multiple models.
環境情報&前提条件
- Ruby 3.2.1
- Rails 7.0.0
実装したい内容
- 以下の記事の続きです。
- ポリモーフィック関連の共通処理を例として記載しますが、複数モデルに同じ処理を記載している場合同様にリファクタリング可能です。
- 以下のように3つのモデルで全く同じ処理を記載しているケースを想定。(関係する処理のみ抽出して記載)
like.rb
class Like < ApplicationRecord
# 複数モデルで以下のような全く同じ処理を記載している
after_create :create_notification
private
def create_notification
Notification.create(user: post.user, action: self, action_type: self.class.name )
end
end
comment.rb
class Comment < ApplicationRecord
# 複数モデルで以下のような全く同じ処理を記載している
after_create :create_notification
private
def create_notification
Notification.create(user: post.user, action: self, action_type: self.class.name )
end
end
repost.rb
class Repost < ApplicationRecord
# 複数モデルで以下のような全く同じ処理を記載している
after_create :create_notification
private
def create_notification
Notification.create(user: post.user, action: self, action_type: self.class.name )
end
end
実装手順
- ※このリファクタリングにたどり着く前に、親クラスのApplicationRecordに共通処理を記述しましたがうまく動作しませんでした。
- ※そのため、Moduleとして共通処理を切り出す形で記載いたします。各Modelに共通の親クラスを設定している場合は、親クラスに共通処理を記載する形で問題ありません。
手順1
-
app/models/concerns/
配下にModuleファイルを作成する。Moduleファイルを配置するディレクトリは非常に大事です。左記の場所に配置してください。 - 今回は共通処理が通知レコードの作成処理なので。
NotificationCreator
というモジュールを作成することにいたします。
手順2
- 手順1で作成したモジュールに共通処理を移行
app/models/concerns/notification_creator.rb
module NotificationCreator
# 3つのモデルで記述している全く同じ処理をモジュールに移植
def create_notification
notification = Notification.create(user: post.user, action: self, action_type: self.class.name)
end
end
手順3
- 各Modelから共通処理を削除し、モジュールをincludeする。
- 3つのモデルは最終的に以下の形になります。
like.rb
class Like < ApplicationRecord
# 処理を移行したモジュールをinclude
include NotificationCreator
after_create :create_notification
end
comment.rb
class Comment < ApplicationRecord
include NotificationCreator
after_create :create_notification
end
repost.rb
class Repost < ApplicationRecord
include NotificationCreator
after_create :create_notification
end
補足:なぜリファクタリングをする必要があるか
- 上記のようにリファクタリングをするメリットとして、共通処理を変更した場合にコードの変更箇所が1箇所で済むというものがあります。
- 例えば、
create_notification
の中で通知レコードを作成すると共に「メール送信を同時に行う」という改修が新たに必要になったとします。- 3モデルに同じ処理が書いてあった場合、この改修により3モデルすべての
create_notification
を修正する必要があります。3回同じ修正をする必要が出てきます。 - 一方で、モジュールに共通処理を移行した場合、モジュールの
create_notification
のみを編集するだけで問題ありません。1箇所コードを修正することで、includeした3つのモデル全てに変更を適用することが可能です。
- 3モデルに同じ処理が書いてあった場合、この改修により3モデルすべての