【问题标题】:Multiple Inheritance Columns in Rails?Rails中的多个继承列?
【发布时间】:2014-05-16 02:03:39
【问题描述】:

我有一个活动记录类(动物),它有一个类型列和一个性别列。理论上,我想创建多个继承自 Animal 的类:

    class Animal < ActiveRecord::Base
        self.inheritance_column = {‘type’, ‘gender’}
    end

然后添加继承的类:

    class Dog < Animal
    end

    class Giraffe < Animal
    end

    class Male < Animal
    end

可以这样做吗?我知道默认情况下任何名为“type”的列都是继承列,但我想定义多个列作为继承列。不确定它是否有效,但我尝试使用上面的数组。

【问题讨论】:

  • 除非我没有看到任何东西,否则拥有多个继承列并没有什么意义,因为type 列仅仅是一个鉴别器。您当然可以使用这些列执行连接。您能解释一下为什么要在 STI 中使用多个列吗?
  • 基本上,我希望有一个包含(并且仅处理)性别的课程,但可以包含所有类型的动物。 (我以性别和动物为例)。因此,例如,女性班级可能包括怀孕持续时间等字段。然而,所有的长颈鹿都可能包括一个像颈长这样的场。我正在使用的数据并没有那么复杂,所以我希望将所有“动物”都包含在同一个表中,但根据其性别或物种类型将某些字段设为空。加入会是更好的选择吗?
  • 嗯,我明白了。是的,加入肯定是更好的选择。如果我们以面向对象的方式来考虑,动物“有”性别(即构成)。如果您愿意(如果在我之前没有其他人这样做的话),我可以很快发表一篇更好的文章来说明这一点。

标签: ruby-on-rails inheritance activerecord


【解决方案1】:

我今天正试图这样做......

答案似乎是 ...但也有点像。

我们可以做的是将self.inheritance_column设置为其他东西,这样它就不会干扰,然后开始构建我们自己需要的东西:

假设我们的类如下所示:

class Animal < ActiveRecord::Base
  self.inheritance_column = nil
end

class FemaleDog < Animal
end
class MaleDog < Animal
end

class FemaleGiraffe < Animal
end
class MaleGiraffe < Animal
end

如果我们有一种公式化的方式将两列组合成名称,我们可以在 Animal 类上创建一个类似 auto_become 的方法来帮助实例化正确的类:

class Animal < ActiveRecord::Base
  self.inheritance_column = nil

  self.auto_become
    becomes("#{gender}#{type}".constantize)
  end
end

现在,每当我们发现动物时,我们都需要添加一个auto_become 调用:

# normal STI
Animal.where(:type => "Dog").all
=> (returns objects with class of "Dog")
# hacky STI
Animal.where(:type => "Dog", :gender => "Female").all
=> (returns objects with class of "Animal")
Animal.where(:type => "Dog", :gender => "Female").map(&:auto_become)
=> (returns objects with class of "Dog")

我们还需要修复我们希望像 FemaleDog.all 这样的调用仅查询 where(:type =&gt; "Dog", :gender =&gt; "Female")FemaleDog.new 以使用 type = "Dog"gender = "Female" 初始化的方面;这两个都被我们的 hacky STI 打破了。 default_scope 是解决这两个问题的一种方法(但请注意,使用 default_scope 存在缺陷,这通常不是一个好主意):

class FemaleDog < Animal
  default_scope -> { where(:type => "Dog", :gender => "Female") }
end

而且我确信还有很多其他的事情需要解决。为了让它像内置的 STI 一样神奇,基本上需要挂钩/覆盖所有东西......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多