Rails单表继承 - 从超类查询调用子类方法

时间:2015-04-20 01:28:11

标签: ruby-on-rails single-table-inheritance

考试是SatTest和ActTest的父母,如此

class Exam < ActiveRecord::Base
     self.inheritance_column = :test_type

       def self.find_sti_class(type_name)
           type_name = self.name
           super
       end
end

class ActTest < Exam
    def self.sti_name
        'ACT'
    end

    def some_method
    end
end

class SatTest < Exam
    def self.sti_name
        'SAT'
    end

    def some_method
    end
end

当我查询Exam.find(1)时,它会返回一个Exam实例。因此,当我在此对象上调用some_method时,它会调用返回undefined method some_method而不是在其子类上调用该方法。

将方法发送到子类而不必再次查询的最佳方法是什么?我知道我可以做到这一点,但看起来非常h​​acky

class Exam < ActiveRecord::Base
    def some_method
        if self.type == "SAT"
            SatTest.find(self.id).some_method
        elsif self.type == "ACT"
            ActTest.find(self.id).some_method
        end
    end
end

更新 关于类型字段,我已经编辑了上面的模型(在我的应用程序中将其重命名为test_type)。我正在使用rails 4.2.1。

1 个答案:

答案 0 :(得分:2)

如果正确设置了STI,Rails将初始化正确的对象(即exams表格中有type:string列,或者self.inheritance_column上已定义exam模型)

如果您的查询返回Exam的实例,则表示test_type列为空/无,或者您没有正确设置STI。

class Exam < ActiveRecord::Base
  self.inheritance_column = :test_type

  def some_method
    "called from Exam"
  end
end

class ActTest < Exam
  def some_method
    "called from ActTest"
  end
end

class SatTest < Exam
  def some_method
    "called from SatTest"
  end
end

在控制台中试用

Exam.create name:'SAT', test_type:'SatTest'
 => #<SatTest id: 1, name: "SAT", test_type: "SatTest", created_at: "2015-04-20 01:52:43", updated_at: "2015-04-20 01:52:43"> 

exam = Exam.find 1
 => #<SatTest id: 1, name: "SAT", test_type: "SatTest", created_at: "2015-04-20 01:52:43", updated_at: "2015-04-20 01:52:43">
exam.some_method
 => "called from SatTest"

Reference