LoginSignup
23
18

More than 5 years have passed since last update.

Rails の STI で type カラムに入れる値を変える

Last updated at Posted at 2015-10-02

メモ。STI (Single Table Inheritance) を使ってこんな構造を作りたいとする。

class Task < ActiveRecord::Base
end

class AbstractTask < Task
end

class ConcreteTask < Task
end

STI のデフォルト挙動では type カラムの値にクラス名が入る。AbstractTask の場合には AbstractTask、ConcreteTask の場合には ConcreteTask となる。

が、tasks テーブルを見ているわけで、Task であることはわかっているし、それぞれ abstractconcrete ぐらいにしたい。というただのこだわり。

こうすればできるようだ。

class Task < ActiveRecord::Base
end

class AbstractTask < Task
  class << self
    def find_sti_class(type_name)
      type_name = self.name
      super
    end

    def sti_name
      "abstract"
    end
  end
end

class ConcreteTask < Task
  class << self
    def find_sti_class(type_name)
      type_name = self.name
      super
    end

    def sti_name
      "concrete"
    end
  end
end

訂正。親クラスで定義しないと、Task.first のようにインスタンスを作った場合に、適切に AbstractTaskConcreteTask に変身してくれなかった。こんなかんじになった。

class Task < ActiveRecord::Base
  class << self
    def find_sti_class(type)
      class_name = "#{type.camelize}Task"
      super(class_name)
    end

    def sti_name
      @sti_name ||= self.name == 'ConcreteTask' ? 'concrete' : 'abstract'
    end
  end
end

class AbstractTask < Task
end

class ConcreteTask < Task
end
23
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
18