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_class
とsti_name
を変更するとintegerで扱える。
子クラスの情報を知る必要があるのが少しイケていない点ではあるけど…。
gemにしてみた
毎回書くのが面倒なので、gemにしてみた。
これを使うと
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
と書くことができる。