Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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 向现有模型添加单表继承(STI)_Ruby_Postgresql_Ruby On Rails 4 - Fatal编程技术网

Ruby 向现有模型添加单表继承(STI)

Ruby 向现有模型添加单表继承(STI),ruby,postgresql,ruby-on-rails-4,Ruby,Postgresql,Ruby On Rails 4,我目前有多个非常相似的表。我应该用STI来制作它们 TypeOne < ActiveRecord::Base TypeTwo < ActiveRecord::Base TypeThree < ActiveRecord::Base TypeOne(id: integer, parent_id: integer, created_at: datetime, updated_at: datetime) TypeTwo(id: integer, parent_id: integer,

我目前有多个非常相似的表。我应该用STI来制作它们

TypeOne < ActiveRecord::Base
TypeTwo < ActiveRecord::Base
TypeThree < ActiveRecord::Base

TypeOne(id: integer, parent_id: integer, created_at: datetime, updated_at: datetime)
TypeTwo(id: integer, parent_id: integer, created_at: datetime, updated_at: datetime)
TypeThree(id: integer, parent_id: integer, created_at: datetime, updated_at: datetime)
我还运行了一次迁移,并在所有类型中添加了一个类型列

class AddTypeToTables < ActiveRecord::Migration
  def change
    add_column :type_ones, :type, :string
    add_column :type_twos, :type, :string
    add_column :type_threes, :type, :string
  end
end
我尝试将每个类更改为BaseModel的子类

TypeOne.last.becomes!(BaseModel)
#<BaseModel id: 4, parent_id: 1, created_at: "2015-05-08 18:39:09", updated_at: "2015-09-07 19:42:03">

BaseModel.all
=> []
TypeOne < BaseModel
TypeTwo < BaseModel
TypeThree < BaseModel
TypeOne
执行此操作时,我将失去与现有数据的连接,并且每个模型都显示为空


如何组合现有表?

您已经用PostgreSQL对其进行了标记,我将介绍如何执行我在评论中建议的操作,作为答案:

INSERT INTO base_model SELECT * FROM type_one ORDER BY id ASC;
INSERT INTO base_model SELECT * FROM type_two ORDER BY id ASC;
INSERT INTO base_model SELECT * FROM type_three ORDER BY id ASC;
为了在生产数据集上安全地执行此操作,请将SQL放在db/migrate中的迁移中(即,放在db/migrate/20150907185938_integrate_tables.rb这样的文件中),然后首先在本地数据库上测试它。这会让你非常接近:

class IntegrateTables < ActiveRecord::Migration
  def up
    execute "INSERT INTO base_model SELECT * FROM type_one ORDER BY id ASC;"
    execute "INSERT INTO base_model SELECT * FROM type_two ORDER BY id ASC;"
    execute "INSERT INTO base_model SELECT * FROM type_three ORDER BY id ASC;"
  end

  def down
    raise ActiveRecord::IrreversibleMigration, "It is unclear where original data stops and inserted data begins, can't migrate down"
  end
end
class IntegrateTables

如果此答案对您有效,请将其标记为已接受:)

是否有任何外键引用记录的id(例如键入\ one.id、键入\ two.id等)?如果不是,我建议从一个表中选择并插入到BaseModel的表中,这将更改ID,以便在正确设置主键的情况下不会发生冲突。然后使用继承结构,就像使用itSTI=单表继承一样。要按预期使用它,您需要将所有数据放在一个表中,这是有意义的,谢谢对于生产数据集,有什么干净的方法可以做到这一点吗?在下面的回答中添加了它
TypeOne < BaseModel
TypeTwo < BaseModel
TypeThree < BaseModel
INSERT INTO base_model SELECT * FROM type_one ORDER BY id ASC;
INSERT INTO base_model SELECT * FROM type_two ORDER BY id ASC;
INSERT INTO base_model SELECT * FROM type_three ORDER BY id ASC;
class IntegrateTables < ActiveRecord::Migration
  def up
    execute "INSERT INTO base_model SELECT * FROM type_one ORDER BY id ASC;"
    execute "INSERT INTO base_model SELECT * FROM type_two ORDER BY id ASC;"
    execute "INSERT INTO base_model SELECT * FROM type_three ORDER BY id ASC;"
  end

  def down
    raise ActiveRecord::IrreversibleMigration, "It is unclear where original data stops and inserted data begins, can't migrate down"
  end
end