Добавление внешнего ключа в модель рельсов
Я новичок в рельсах и стараюсь работать всю ночь без везения.
Я создал 3 модели: users
, businesses
и business_hours
. Я также добавил ассоциации (business_hours belongs_to businesses which belongs_to users
) и (user has_one business which has_many business_hours
).
Чтение через онлайн-документы теперь кажется, что теперь мне нужно создать внешние ключи для этих отношений в моих таблицах БД. Как это сделать, используя миграцию Rails ActiveRecord? Я использую PostgreSQL в качестве моей базы данных.
Ответы
Ответ 1
Прежде всего, когда вы используете метод belongs_to, не используйте s
в конце слова: business_hours belongs_to business which belongs_to user
.
Теперь создайте миграцию:
rails generate migration migration_name
И в миграции добавьте столбцы:
class MigrationName < ActiveRecord::Migration
def change
add_foreign_key :business_hours, :businesses
add_foreign_key :businesses, :users
end
end
Запустите rake db:migrate
. Что это.
Ответ 2
Нынешний принятый ответ на это не совсем точный, поскольку он не добавляет внешний ключ базы данных. Он просто добавляет целые столбцы.
В Rails 4.2.x текущий подход:
http://guides.rubyonrails.org/active_record_migrations.html#foreign-keys
Создать перенос:
rails generate migration migration_name
Для существующих столбцов в миграции добавьте внешние ключи, например:
class MigrationName < ActiveRecord::Migration
def change
add_foreign_key :business_hours, :businesses
add_foreign_key :businesses, :users
end
end
Для Rails 4.x или если вы добавляете новый столбец и хотите, чтобы он был внешним ключом, вы можете сделать это, где вы, вероятно, также захотите укажите индекс как истинный, но это не является частью требования для внешнего ключа:
http://edgeguides.rubyonrails.org/active_record_migrations.html#creating-a-migration
class MigrationName < ActiveRecord::Migration
def change
add_reference :business_hours, :business, index: true, foreign_key: true
add_reference :businesses, :user, index: true, foreign_key: true
end
end
Ответ 3
Я не пробовал его с PostgreSQL, но, по крайней мере, с MySQL Rails НЕ создают внешние ключи, я имею в виду не реальные внешние ключи уровня db. Все, что они создают, - это целое число, указанное по соглашению. Это означает, что из коробки вы не получаете индекс этого фальшивого внешнего ключа (для более быстрого поиска), а также нет проверки ссылочной целостности уровня db. Для этого вам нужно сделать что-то вроде:
ALTER TABLE your_table ADD CONSTRAINT fk_whatever_you_want_to_name_it FOREIGN KEY (foreign_key_name) REFERENCES another_table(its_primary_key)
В миграции Rails вы можете передать это как строковый аргумент функции "выполнить". Добавление "реального" внешнего ключа также автоматически создает индекс. По крайней мере, для меня это был довольно неприятный сюрприз.
Ответ 4
Rails 5 теперь может добавлять внешний ключ в миграции, см. http://devdocs.io/rails~5.0/activerecord/connectionadapters/schemastatements#method-i-add_foreign_key. Так
add_foreign_key :articles, :authors
создает
ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id")
Если у вас есть нестандартная модель данных, которую вы можете сделать.
add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"
который создает
ALTER TABLE "articles" ADD CONSTRAINT fk_rails_58ca3d3a82 FOREIGN KEY ("author_id") REFERENCES "users" ("lng_id")
Ответ 5
Добавьте schema_plus в свой Gemfile.