Published on

〜Viewにロジック書くの厳しいって〜RailsでUIとロジックを分けるためのPresenter/Decoratorパターンを実例付きで解説❗️

Authors

この記事は ex-crowdworks Advent Calendar 2024の14日目の記事です。

はじめに

今年、株式会社クラウドワークスを退職した@nisyuuです。寒くなってきたのでこたつを出しました。 エンジニアとしてクラウドワークステック(旧クラウドテック)というフリーランスと企業をマッチングするエージェントサービスを開発していました。

Ruby on Railsを利用してアプリを開発していると、ビューロジックが調整されていないため、コードが複雑になる場合があります。 そのような場面で、PresenterやDecoratorの機構を使用することでコードをクリーンにし、管理しやすくすることができます。

本記事では、PresenterとDecoratorの基本的な概念について紹介し、それぞれのメリット、デメリット、実装例を見ていきます。

Presenterとは

Presenterは、モデルに属する表示ロジックを隠蔽するためのクラスです。ビューの責務を分離し、ビューのロジックをコントローラから切り離すことができます。

Presenterのメリットとデメリット

メリット

  • ロジックを分離することでコードの読みやすさが向上する
  • ビューロジックがモデルに依存しなくなる

デメリット

  • 新たなクラスを追加するため、プロジェクトが複雑に見える可能性がある
  • 実装コストが増える

Presenterの実装例

下記は、Presenterを実装するための基本的なコード例です。

class ProductPresenter
  def initialize(product)
    @product = product
  end

  def display_price
    "\#{formatted_price}"
  end

  def stock_status
    @product.stock > 0 ? 'In Stock' : 'Out of Stock'
  end

  private

  def formatted_price
    sprintf('%.2f', @product.price)
  end

  attr_reader :product
end

Decoratorとは

Decoratorは、コンポーネントの機能を拡張するために使用され、クラスの負担を小さくし、純粋な機能に集中することができます。 Railsではactive_decoratorgemが普及しており、それを利用することが推奨されます。

https://github.com/amatsuda/active_decorator

Decoratorのメリットとデメリット

メリット

  • ロジックを再利用しながら、モデルの機能を拡張できる
  • コンポーネントを実装している程度でビューへのロジック転射を調整できる

デメリット

  • 実装するにはDecoratorに関する十分な知識が必要
  • コンポーネントを拡張しすぎると、利用性が低下する可能性がある

Decoratorの実装例

下記はactive_decoratorgemを使用したDecoratorの基本的なコード例です。

class UserDecorator < Draper::Decorator
  delegate_all

  def formatted_name
    "#{object.first_name} #{object.last_name}".titleize
  end
end

Helperを使わずにPresenterとDecoratorを使う理由

RailsのHelperは、ビュー内のロジックを簡潔に記述するための便利な機能ですが、以下のような理由でPresenterやDecoratorを使うことが推奨される場合があります。

再利用性の向上

Helperはビューごとに特化した内容になりがちで、再利用が難しいことがあります。PresenterやDecoratorを使用することで、モデルに紐づくロジックを再利用可能な形で整理できます。

テストのしやすさ

Helperは一般的にテストが困難ですが、PresenterやDecoratorは独立したクラスであるため、単体テストが容易です。

コードの可読性の向上

Helperにロジックを詰め込みすぎると可読性が低下する場合があります。PresenterやDecoratorを導入することで、ロジックを整理し、コードの構造を明確にできます。

責務の分離

Presenterは表示ロジック、Decoratorはモデルの拡張といったように、役割が明確になります。これにより、コード全体の責務が分離され、管理しやすくなります。

おわりに

PresenterとDecoratorは、Railsアプリを深いレベルでカスタマイズするための重要な機構です。Presenterはビューロジックを分離し、Decoratorはモデルの機能を拡張するという個別の役割を持っています。これらを適切に使い分けることで、コードの読みやすさや保守性も高められるでしょう。