Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 为引用自己表的外键创建Rails 5迁移_Ruby On Rails_Postgresql_Ruby On Rails 5_Rails Activerecord_Rails Migrations - Fatal编程技术网

Ruby on rails 为引用自己表的外键创建Rails 5迁移

Ruby on rails 为引用自己表的外键创建Rails 5迁移,ruby-on-rails,postgresql,ruby-on-rails-5,rails-activerecord,rails-migrations,Ruby On Rails,Postgresql,Ruby On Rails 5,Rails Activerecord,Rails Migrations,我正在写一个显示家谱的小狗数据库。 我有一个postgresql表“dogs”,它有一个dog\u id、名称、重量等。 我还希望它有一个母亲id和一个父亲id来存储另一个狗id 首先,这样做有效吗? 我将如何为Rails5编写迁移 或者我应该有另一张表格“parentage”,它只是把狗和其他狗联系在一起?肯定至少要有第二张表格 我建议添加一个配对或窝模型,并将您的狗与之对应,因为繁殖者可能会再次拥有相同的配对 P>由于层次结构在性能上存在问题,而且使用更深层次的嵌套数据,您可以考虑为另一个

我正在写一个显示家谱的小狗数据库。 我有一个postgresql表“dogs”,它有一个dog\u id、名称、重量等。 我还希望它有一个母亲id和一个父亲id来存储另一个狗id

首先,这样做有效吗? 我将如何为Rails5编写迁移


或者我应该有另一张表格“parentage”,它只是把狗和其他狗联系在一起?

肯定至少要有第二张表格

我建议添加一个配对或窝模型,并将您的狗与之对应,因为繁殖者可能会再次拥有相同的配对

<> P>由于层次结构在性能上存在问题,而且使用更深层次的嵌套数据,您可以考虑为另一个或两个表中的每个狗存储祖先,以便能够对网站快速检索它们。


我建议,因为它在这种情况下提供了最好的性能(经常阅读,不经常编写)。

肯定要至少使用第二个表

我建议添加一个配对或窝模型,并将您的狗与之对应,因为繁殖者可能会再次拥有相同的配对

<> P>由于层次结构在性能上存在问题,而且使用更深层次的嵌套数据,您可以考虑为另一个或两个表中的每个狗存储祖先,以便能够对网站快速检索它们。


我建议,因为它在这种情况下提供了最好的性能(经常阅读,不经常写作)。

我不同意neongrau的观点。你不需要第二张桌子就能做到这一点。它可以通过在您的dogs表中创建动态自联接来完成。首先在单个模型中声明所有关系,并分别声明它们的外键:

models/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
classdog
然后,您将运行一个引用爸爸妈妈的迁移:

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
class CreateDogs
现在我们通过手动建立关联来测试它:

   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"...>
kid=Dog.create(名称:“漫游者”)
=> #
ma=Dog.create(名称:“Susie”)
=> #
pa=狗。创建(名称:“Doug”)
=> #
kid.mom_id=2
孩子,救命
孩子,妈妈
=> #
kid.dad_id=3
孩子,救命
孩子,爸爸
=> #
妈妈,孩子们#
爸爸,孩子们#

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

我不同意neongrau的观点。你不需要第二张桌子就能做到这一点。它可以通过在您的dogs表中创建动态自联接来完成。首先在单个模型中声明所有关系,并分别声明它们的外键:

models/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
classdog
然后,您将运行一个引用爸爸妈妈的迁移:

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
class CreateDogs
现在我们通过手动建立关联来测试它:

   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"...>
kid=Dog.create(名称:“漫游者”)
=> #
ma=Dog.create(名称:“Susie”)
=> #
pa=狗。创建(名称:“Doug”)
=> #
kid.mom_id=2
孩子,救命
孩子,妈妈
=> #
kid.dad_id=3
孩子,救命
孩子,爸爸
=> #
妈妈,孩子们#
爸爸,孩子们#

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

很高兴不同意你的观点;)STI很好,也很简单,但是当您需要遍历一棵树时,对于祖先中的每个级别(妈妈和爸爸),您都会遇到一个n+2 sql查询问题。因此,对于曾祖父母,您已经在使用n+2+4+8 sql查询来呈现家谱了。站点性能将不存在。所有内容都可以缓存。你可以创建一个方法来加载ID的嵌套,缓存它并让迭代器使用它。我确实明白neongrau关于性能的观点,我将研究用于重构的便捷ClosureTree工具。因为它目前只是在本地进行试验,所以我不太担心性能。很好,有相关父母的基础模型狗也可以。在闭包树中,您可以添加一个稍后的点,该点将充当缓存。这就是所有不同层次结构树解决方案(嵌套集、相邻列表、闭包树)的用途。在闭包树中,您将为每个狗添加新根,并通过将父节点作为子节点添加到树中来反转方向。即使是父母也会在该树的不同层次上多次存在,这样你就可以在一个sql查询中读取任何狗的完整祖先行。@neongrau如果你真的不需要任何花哨的或非规范化的东西来拉出整个树,PostgreSQL支持递归的
查询。很高兴也不同意你的意见;)STI很好,也很简单,但是当您需要遍历一棵树时,对于祖先中的每个级别(妈妈和爸爸),您都会遇到一个n+2 sql查询问题。因此,对于曾祖父母,您已经在使用n+2+4+8 sql查询来呈现家谱了。站点性能将不存在。所有内容都可以缓存。你可以创建一个方法来加载ID的嵌套,缓存它并让迭代器使用它。我确实明白neongrau关于性能的观点,我将研究用于重构的便捷ClosureTree工具。自从