Подтвердить что ты не робот

Добавление внешнего ключа в модель рельсов

Я новичок в рельсах и стараюсь работать всю ночь без везения.

Я создал 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 в качестве моей базы данных.

4b9b3361

Ответ 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.