简体   繁体   English

Rails和参照完整性

[英]Rails and referential integrity

I would like to know if it's possible to write a migration instead of of the following raw SQL statement: 我想知道是否可以编写迁移而不是以下原始SQL语句:

execute <<-SQL
  ALTER TABLE records
    ADD CONSTRAINT fk_records_domains
    FOREIGN KEY (domain_id)
    REFERENCES domains(id) ON DELETE CASCADE
SQL

I would like avoid using sql because i'm getting problems when trying to rollback such migration: 我想避免使用sql,因为在尝试回滚此类迁移时遇到问题:

execute <<-SQL
  ALTER TABLE records
    DROP FOREIGN KEY fk_records_categories
SQL





rake db:rollback
==  Integrity: reverting ======================================================
-- execute("      ALTER TABLE records\n        DROP FOREIGN KEY                                      fk_records_categories\n")
rake aborted!
An error has occurred, all later migrations canceled:

Mysql2::Error: Error on rename of './BlackshardDev/records' to './BlackshardDev/#sql2-44cc-16c' (errno: 152):       ALTER TABLE records
    DROP FOREIGN KEY fk_records_categories

I know that activerecord can handle the referential integrity but i would like to be able to manage it also with the backend. 我知道activerecord可以处理参照完整性,但我希望也可以通过后端对其进行管理。 Thanks 谢谢

According to the Rails Migrations guide : 根据Rails迁移指南

The Active Record way claims that intelligence belongs in your models, not in the database. Active Record方式声称智能属于您的模型,而不属于数据库。 As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not heavily used. 这样,诸如触发器或外键约束之类的将某些智能推回数据库的功能并未得到广泛使用。

...

Although Active Record does not provide any tools for working directly with such features, the execute method can be used to execute arbitrary SQL. 尽管Active Record没有提供任何直接使用这些功能的工具,但是execute方法可用于执行任意SQL。 You could also use some plugin like foreigner which add foreign key support to Active Record (including support for dumping foreign keys in db/schema.rb). 您还可以使用某些插件,例如foreigner ,它向Active Record添加了外键支持(包括对在db / schema.rb中转储外键的支持)。

Foreigner's add_foreign_key and remove_foreign_key probably do what you're asking for, but I don't have any direct experience with it. 外国人的add_foreign_keyremove_foreign_key可能会满足您的要求,但是我对此没有任何直接的经验。

For anyone that is lookig for a solution example here it is, migration and it's rollback working: 对于任何在这里寻找解决方案示例的人来说,它都是迁移和回滚工作:

  def up
    change_table :records do |t|
        t.foreign_key :domains, :dependent => :delete
    end
    change_table :cryptokeys do |t|
        t.foreign_key :domains, :dependent => :delete
    end
    change_table :domainmetadata do |t|
        t.foreign_key :domains, :dependent => :delete
    end

  end

  def down
    change_table :records do |t|
        t.remove_foreign_key :domains
    end
    change_table :cryptokeys do |t|
        t.remove_foreign_key :domains
    end
    change_table :domainmetadata do |t|
        t.remove_foreign_key :domains
    end
  end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM