has_many孩子和has_many父母

时间:2011-05-20 09:25:24

标签: ruby-on-rails associations database-relations

我试图弄清楚模型之间的复杂关系。 我有一个名为“Concept”的模型,它有两个继承类型,称为“技能”和“职业”。基本上这意味着每个概念代表一个类别,但是当进入hierychal树时,概念也可以是技能或职业。

我正在使用STI解决这个层次问题。所以我的Concepts表的架构如下所示:

class CreateConcepts < ActiveRecord::Migration
  def self.up
    create_table :concepts do |t|
      t.string :uri, :null => false, :length => 255
      t.string :type, :null => true, :length => 255
      t.integer :isco_code, :null => true
      t.timestamps
    end
  end

  def self.down
    drop_table :concepts
  end
end

类型列确定概念是真实的“概念”还是“技能”/“职业”。 然而现在的问题是以下关系:

修改

  
      
  • 概念可以属于单亲概念
  •   
  • 职业可以属于单亲概念
  •   
  • 技能可以属于多个父概念
  •   
  • 技能没有孩子
  •   
  • 职业没有孩子
  •   

基本上你有这样的东西:

>                             concept1
>                  concept2                  concept3
>        concept4       concept5        concept6     concept7    skill1 
> occup1   skill2 occup2    skill5
> occup7    skill2  occup3   skill4
> occup4    skill1 occup8

我希望图片有点清楚我想解释的内容。 目前我已经创建了以下迁移以尝试解决父子关系,但我不确定如何将这与关联映射...

class CreateConceptLinks < ActiveRecord::Migration
  def self.up
    create_table :concept_links do |t|
      t.integer :parent_id, :null => false
      t.integer :child_id, :null => false
      t.timestamps
    end
  end

  def self.down
    drop_table :concept_links
  end
 end

我最终想要的是以下可能性:

concepta.parents => a Concept object
conceptb.children => an array of Conept objects
Occupation.parents => a Concept object
Occupation.children => []
Skill.parents => an array of Concept objects
Skill.children => []

希望这甚至可能......

1 个答案:

答案 0 :(得分:4)

您可以在rails中建模层次关系。您的迁移大部分都在那里。添加以下关系应该允许您执行您想要的方法调用:

def Concept < ActiveRecord::Base
  has_many :child_links, :class_name => 'ConceptLink', :foreign_key => 'parent_id'
  has_many :children, :through => :child_links

  has_many :parent_links, :class_name => 'ConceptLink', :foreign_key => 'child_id'
  has_many :parents, :through => :parent_links
end

def ConceptLink < ActiveRecord::Base
  belongs_to :child, :class_name => "Concept"
  belongs_to :parent, :class_name => "Concept"
end

我还要看一下this blog posting,它可以很好地解释rails中的父子映射。