为引用其自己的表的外键创建Rails 5迁移

时间:2017-10-25 20:26:38

标签: ruby-on-rails postgresql ruby-on-rails-5 rails-activerecord rails-migrations

我正在写一个显示家谱的小狗数据库。 我有一个postgresql表'狗'有dog_id,名称,重量等。 我还希望它有一个mother_id和一个存储另一个dog_id的father_id。

首先,这甚至有用吗? 我将如何为Rails5编写迁移?

或者,我是否应该将另一张桌子'亲子'用于将狗彼此联系起来?

2 个答案:

答案 0 :(得分:2)

我不同意neongrau。你不需要第二张桌来实现这一目标。这可以通过在狗桌上进行动态自我加入来完成。您首先要在单个模型中声明所有关系及其外键:

<强>模型/ dog.rb:

class Dog < ActiveRecord::Base
  belongs_to :mom, class_name: "Dog", foreign_key: "mom_id"
  belongs_to :dad, class_name: "Dog", foreign_key: "dad_id"
  has_many :kids, class_name: "Dog"
end

然后你会运行一个引用妈妈和爸爸的迁移:

class CreateDogs < ActiveRecord::Migration
  def change
    create_table :dogs do |t|
      t.string :name
      t.integer :age
      t.references :mom
      t.references :dad
      t.integer :dog_id

      t.timestamps null: false
    end
end

现在我们通过手动构建我们的关联来测试它:

   kid = Dog.create(name: "Rover")
    => #<Dog id: 8, name: "Rover"..>

   ma = Dog.create(name: "Susie")
   => #<Dog id: 2, name: "Susie"..>

   pa = Dog.create(name: "Doug")
   => #<Dog id: 8, name: "Doug"..>

kid.mom_id = 2
kid.save

kid.mom
 => #<Dog id: 2, name: "Susie"...>

kid.dad_id = 3
kid.save

kid.dad
 => #<Dog id: 3, name: "Doug"...>


ma.kids << kid
ma.save

ma.kids
 => #<Dog id: 1, name: "Rover"...>

pa.kids << kid 
pa.save

pa.kids
 => #<Dog id: 1, name: "Rover"...>

现在你有一种动态的关系,狗可以有多个孩子,可能属于母亲和父亲。

答案 1 :(得分:0)

绝对要去第二张桌子。

我建议添加一个Pairing或Litter Model并用你的狗来映射,因为育种者可能会再次配对。

由于层次结构在性能方面存在问题,因此您可以考虑将更多嵌套数据存储在另一个或两个表中,以便能够为网站快速检索它们。

我建议https://github.com/ClosureTree/closure_tree因为它为这种情况提供了最佳性能(经常阅读,不经常写)。