Ruby
Rails

STIのtypeカラムにintegerを使う

More than 1 year has passed since last update.

integerを使いたくなったのでやってみた。

通常のSTI

class Message < ActiveRecord::Base
end

class WarningMessage < Message
end

class ErrorMessage < Message
end

こんな感じにしておくと、messagesテーブルのtypeカラム

  • Message
  • WarningMessage
  • ErrorMessage

という文字列が格納される。

typeをintegerにしたSTI

class Message < ActiveRecord::Base
  TYPE_VALUE = 0

  class << self
    def find_sti_class(type)
      case type
      when WarningMessage::TYPE_VALUE
        WarningMessage
      when ErrorMessage::TYPE_VALUE
        ErrorMessage
      else
        self
      end
    end

    def sti_name
      case self
      when WarningMessage
        WarningMessage::TYPE_VALUE
      when ErrorMessage
        ErrorMessage::TYPE_VALUE
      else
        self::TYPE_VALUE
      end
    end 
  end
end

class WarningMessage < Message
  TYPE_VALUE = 1
end

class ErrorMessage < Message
  TYPE_VALUE = 2
end

こんな感じで、find_sti_classsti_nameを変更するとintegerで扱える。

子クラスの情報を知る必要があるのが少しイケていない点ではあるけど…。

gemにしてみた

毎回書くのが面倒なので、gemにしてみた。

sti_type_customizable

これを使うと

class Message < ActiveRecord::Base
  include StiTypeCustomizable
  self.sti_type_value = 0
  sti_child_classes [WarningMessage, ErrorMessage]
end

class WarningMessage < Message
  self.sti_type_value = 1
end

class ErrorMessage < Message
  self.sti_type_value = 2
end

と書くことができる。