POROとは

PORO(Plain Old Ruby Object)は、Active Recordなどを継承していない、通常のRubyクラスのこと。モデルが肥大化するのを防ぎ、責任を分離するためのデザインパターン。

背景

構造化データをscriptタグに動的に埋め込む実装を行う際、以下の問題に直面:

1. Helperに書く場合

  • ✅ Viewに関連するので自然
  • ❌ テストが書きづらい
  • ❌ Helperのテストは一般的でない

2. Modelに書く場合

  • ✅ テストが書きやすい
  • ❌ モデルが肥大化する
  • ❌ 特定用途のみのメソッドでモデルが複雑化

POROを使う利点

メリット

  1. テストの書きやすさを維持 - モデルと同様にテスト可能
  2. モデルの肥大化を防ぐ - 責任を分離
  3. 可読性の向上 - 用途が明確なクラス設計
  4. 再利用性 - 独立したクラスとして他の場所でも使える

実装例

# app/poros/book_structured_data.rb
class BookStructuredData
  def initialize(book)
    @book = book
  end

  def to_json
    {
      '@context': 'http://schema.org/',
      '@type': 'Book',
      'title': @book.title,
      'description': @book.description,
      'value': @book.id
    }.to_json
  end
end

使い方

# Viewで使用
book = Book.find(1)
structured_data = BookStructuredData.new(book).to_json

まとめ

POROは以下のような場合に有効:

  • モデルに書くには用途が限定的すぎるメソッド
  • ビジネスロジックをモデルから分離したい場合
  • テストしやすい設計を維持したい場合

参考リンク