Рельсы и ссылочная целостность - PullRequest
0 голосов
/ 27 февраля 2012

Я хотел бы знать, возможно ли написать миграцию вместо следующего необработанного оператора 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 ]

3 голосов
/ 27 февраля 2012

Согласно руководству Rails Migrations :

Способ Active Record утверждает, что интеллект принадлежит вашим моделям, а не базе данных. Таким образом, такие функции, как триггеры или ограничения внешнего ключа, которые возвращают часть этих сведений обратно в базу данных, не используются интенсивно.

...

Хотя Active Record не предоставляет никаких инструментов для работы непосредственно с такими функциями, метод execute может использоваться для выполнения произвольного SQL. Вы также можете использовать такой плагин, как иностранец , который добавляет поддержку внешнего ключа в Active Record (включая поддержку для выгрузки внешних ключей в db / schema.rb).

Иностранец add_foreign_key и remove_foreign_key, вероятно, делают то, что вы просите, но у меня нет прямого опыта с этим.

2 голосов
/ 28 февраля 2012

Для всех, кто ищет пример решения здесь, миграция и откат работает:

  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
...