Внешние ключи с ActiveRecord Rails:: Миграция?

Я новичок в Ruby on Rails (я знаю, что Ruby просто прилично) и, глядя на инструменты миграции, звучит потрясающе. Схемы базы данных могут, наконец, (легко) перейти в исходный контроль.

Теперь моя проблема с этим. При использовании Postgres в качестве базы данных он не устанавливает внешние ключи. Я хотел бы получить преимущества внешних ключей в моей схеме, такие как ссылочная целостность. Итак, как мне применить внешние ключи с Migrations?

Ответы

Ответ 1

Философия Rails заключается в том, что проверка целостности - это бизнес-логика, которая принадлежит модели. Вот почему вы видите, что видите в БД; what_id - это просто int, а не "реальный" fk. Это не ошибка, ее по дизайну и немного причудливая. Как правило, единственная причина, побуждающая людей работать с fks на уровне БД, - это когда к БД обращается более чем одно приложение или его устаревшая система. Существует много дискуссий и замечательных ссылок здесь: Почему миграция Rails определяет внешние ключи в приложении, но не в базе данных?

Ответ 2

Проверьте это: http://github.com/matthuhiggins/foreigner

Но сначала убедитесь, что вы действительно нуждаетесь в них (например, ссылочная целостность - это то, что теоретически не должно ломаться, пока ваш код в порядке, и вы знаете о :dependent => :destroy и разнице между user.delete и user.destroy)..

Ответ 3

Существует несколько доступных плагинов (поиск google) для Rails, которые будут создавать внешние ключи для вас, когда вы используете специальный символ в ваших миграциях (foreign_key_migrations - один из книги Advanced Rails Recipes). Просто имейте в виду, что Rails не очень хорошо работает с этой концепцией, особенно когда вы пытаетесь удалить объекты (как упоминалось в glebm).

Ответ 4

Я только что наткнулся на этот пост. Может быть, кто-то найдет это полезным. То, как создаются ограничения:

http://guides.rubyonrails.org/migrations.html#using-reversible

class ExampleMigration < ActiveRecord::Migration
def change
create_table :products do |t|
  t.references :category
end

reversible do |dir|
  dir.up do
    #add a foreign key
    execute <<-SQL
      ALTER TABLE products
        ADD CONSTRAINT fk_products_categories
        FOREIGN KEY (category_id)
        REFERENCES categories(id)
    SQL
  end
  dir.down do
    execute <<-SQL
      ALTER TABLE products
        DROP FOREIGN KEY fk_products_categories
    SQL
  end
end

add_column :users, :home_page_url, :string
rename_column :users, :email, :email_address
end