Внешние ключи с 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