行動すれば次の現実

Webエンジニアが書くテック中心の個人ブログ

静的クラスっぽくRubyのモジュールを使いたい

Rubyのモジュール(module)といえばミックスインというイメージが強い。

ミックスインは便利だが、わざわざミックスインで組み込まずに、ユーティリティクラスのようにそのままメソッドを呼び出したいケースがある。 (Javaでいう静的クラスを定義して静的メソッドを呼び出すイメージ)

モジュールでもそのようなことが実現できる

module HashModule
  extend ActiveSupport::Concern

  def self.to_hash(list)
    hash = { entities: {}, orders: [] }
    orders = []
    list.each do |data|
      orders << data.id
      hash[:entities][data.id] = data
    end
    hash[:orders] = orders
    hash.to_h
  end
end

products = Product.all
HashModule.to_hash(products)

まとめて定義したいときは class << self を使うほうがタイプ数が減っておすすめ。

module HashModule
  extend ActiveSupport::Concern

  class << self
    def to_hash(list)
      hash = { entities: {}, orders: [] }
      orders = []
      list.each do |data|
        orders << data.id
        hash[:entities][data.id] = data
      end
      hash[:orders] = orders
      hash.to_h
    end
  end
end

products = Product.all
HashModule.to_hash(products)