根据对象自己的属性动态设置has_many或has_one

时间:2015-04-23 15:59:36

标签: ruby-on-rails ruby-on-rails-3 activerecord

在类中,我需要根据对象*自己的属性动态设置has_many或has_one关联(因此外来对象不需要更改)。

类似的东西:

class Child < ActiveRecord::Base
   if orphan == true #<-- I can't find the good solution for this condition
     has_one :parent
   else 
     has_many :parents
   end
end
上课#34>父母&#34;我需要保留的课程:

class Parent < ActiveRecord::Base
  belongs_to :children #this is true if the child is orphan or not
end

有办法吗?

以防万一:我使用的是rails 3.2.14

1 个答案:

答案 0 :(得分:1)

我的第一个想法是使用单表继承,因为Orphan是一种具有不同行为的特定类型的孩子。

在确定这是否是正确的路线时,我发现this post非常有用。

如果您选择使用STI,您最终会得到类似......

的内容
class Child < ActiveRecord::Base
end

class Orphan < Child
  has_one :parent
end

class StereotypicalFamilyUnit < Child
  has_many :parents
end

Rails也会假设并期望你有一个&#34;类型&#34; Child表中的字符串列。当您调用Orphan.new时,它将创建一个类型为&#34; Orphan的孩子。&#34;如果你这样做了,那么,Orphan.first&#34;它基本上是在做Child.where(类型:&#34; Orphan&#34;)。首先是在幕后。

另一个选项(我最终选择在一个代替STI的应用程序中选择)将是suggested and use scopes的布尔值,可能看起来像:

class Child < ActiveRecord::Base
  has_many :parents

  scope :orphan, -> { where(orphan: true) }
end

这使得您可以改为调用Child.orphan.new或Child.orphan.first,并在orphan为true时在视图/控制器中执行不同的操作。然后,您也可以按照this prior post中的建议为孤儿创建自定义验证。