はじめに
皆様初めまして。プログラミングスクールで現在 Ruby on Rails を勉強しております、うーさんと申します。
2023 年 4 月よりプログラマーへの門を叩いてから早半年の月日が経ちました。
概要
Ruby on Rails
には MVC 機能において、Model や Controller のコードの重複や肥大化(「Fat Model
」,「Fat Controller
」)を防ぐために、共通的なロジックを部分ごとにモジュールやオブジェクトとして分離する役割を果たす concerns
, helpers
,decorators
といったファイルや概念が存在します。
とは言っても、結局それって何を書くの?どのファイルにどのようなメソッドを書けばいいのか?と疑問に思いましたので、深掘りも兼ねてこの度初めて技術記事にさせていただきました。
💡 誤った知識を記載してしまう場合がございます。
至らぬ点等何かございましたら、お手数ですがご教示いただけますと幸いです。
concerns
- Rails アプリケーション内で同じロジックを複数の場所で再利用するための仕組み。これにより、コードの整理、管理、保守が容易になる。
-
ActiveSupport::Concern
は、Rails が提供するモジュールの拡張機能で、モジュールをより簡潔に使うためのもの。
Controller Concerns
Controller で使う特定の機能やロジック(例: ログインチェック、特定の設定の読み込みなど)を別のモジュールとして分離し、複数の Controller 間でその機能やロジックを共有できる。
同じロジックを複数の Controller で繰り返し書くのではなく、一箇所にまとめて管理し、必要な Controller で簡単にそのロジックを再利用することができる。
例:
複数の Controller で使用する set_params
のようなメソッドを concern
として定義。
module ParamSet
extend ActiveSupport::Concern
#extendを使用することで、ActiveSupport::Concernのメソッドをクラスメソッドとして追加。
private
def set_params
params.require(:model_name).permit(:attribute1, :attribute2, ...)
end
end
複数の Controller でこのモジュールをインクルードすることで、そのロジックを再利用できる。
class SomeController < ApplicationController
include ParamSet
end
Model Concerns
Model で使う特定の機能やビジネスロジック(例: 共通のバリデーション、スコープ、メソッドなど)を別のモジュールとして分離し、複数の Model 間でその機能やロジックを共有するためのもの。
同じロジックを複数の Model で繰り返し書くのではなく、一箇所にまとめて管理し、必要な Model で簡単にそのロジックを再利用することができる。
(ビジネスロジック…アプリケーションの核心的な機能や動作を担当する部分のこと。アプリケーションの主要な動作やルールを定義するもの。)
例: 複数の Model で、特定のカラム(例: name
)の値を大文字に変換して保存したい。
module CapitalizeName
extend ActiveSupport::Concern
included do
before_save :upcase_name
end
private
def upcase_name
self.name = name.upcase
end
end
このモジュールを含む Model は、インクルードすることでそのロジックを再利用できる。
class Product < ApplicationRecord
include CapitalizeName
end
class Brand < ApplicationRecord
include CapitalizeName
end
helpers
-
app/helpers
に配置されており、view で使うための補助メソッドを提供するもの。主に表示ロジックやマークアップの生成のためのメソッドが扱われる。 - Model に依存しない、アプリケーション全体で使われる可能性のある view 関連の小さなタスクや操作に適してる。
【例: 日付を特定のフォーマットで表示するメソッドなど】
module DateHelper
def formatted_date(date)
date.strftime('%Y年%m月%d日')
end
end
decorators
- Model のビジネスロジックと view の表示ロジックを分離するために使われる view ヘルパー。
- Model のデータや関連するロジックを、view 向けに整形・装飾するためのメソッドを書く。
- Rails のデフォルトディレクトリとしては存在しないので、『
draper
』という gem を使用して実装する。
【例: ユーザーのフルネームを表示するメソッドなど】
class UserDecorator < Draper::Decorator
delegate_all
def full_name
"#{object.first_name} #{object.last_name}"
end
end
まとめ
concerns
:Controller や Model のビジネスロジックの複雑性や共通性を解消する役割
helpers
:Model に依存せず、一般的な view 関連の小タスクや操作するためのメソッドをまとめる役割
decorators
:Model のデータに依存して、view の表示に関するロジックをまとめる役割
以上のように認識して使い分けたら良さそうだということがわかりました。
参考にした記事
【Rails】decorator, model, helper の使い分け
ActiveSupport::Concern の使い方としくみ - Qiita
extend Activesupport::Concern について - Qiita
helper と decorator の使い分け - Qiita