Rails和参照完整性

时间:2012-02-27 00:34:55

标签: mysql sql ruby-on-rails referential-integrity

我想知道是否可以编写迁移而不是以下原始SQL语句:

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

我想避免使用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

我知道activerecord可以处理引用完整性,但我希望能够使用后端来管理它。 感谢

2 个答案:

答案 0 :(得分:3)

根据Rails Migrations guide

  

Active Record方式声称智能属于您的模型,而不属于数据库。因此,诸如触发器或外键约束之类的功能(将一些智能推回到数据库中)并没有被大量使用。

     

...

     

虽然Active Record没有提供任何直接使用这些功能的工具,但execute方法可用于执行任意SQL。您还可以使用一些插件,如foreigner,它为Active Record添加外键支持(包括支持在db / schema.rb中转储外键)。

外国人add_foreign_keyremove_foreign_key可能会按照您的要求行事,但我没有任何直接经验。

答案 1 :(得分:2)

对于正在寻找解决方案示例的任何人来说,迁移及其回滚工作是:

  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