Уникальный внешний ключ в миграции rails

в файле миграции я добавляю внешний ключ, используя синтаксис ниже.

class CreatePreferences < ActiveRecord::Migration
  def change
    create_table :preferences do |t|
      t.integer :user_id, null: false
      t.timestamps null: false
    end
    add_foreign_key :preferences, :users, column: :user_id, dependent: :destroy, :unique => true
  end
end

но :unique => true не работает.

mysql> show indexes from preferences;
+-------------+------------+---------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table       | Non_unique | Key_name            | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------+------------+---------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| preferences |          0 | PRIMARY             |            1 | id           | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| preferences |          1 | fk_rails_87f1c9c7bd |            1 | user_id      | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------------+------------+---------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

как правильно добавить уникальный внешний ключ с помощью миграции?

я мог бы добавить проверки уникальности в самой модели. Но это не будет надежным, если у меня будет несколько работающих. (ссылка)

2 ответов


class CreatePreferences < ActiveRecord::Migration
  def change
    create_table :preferences do |t|
      t.integer :user_id, null: false
      t.timestamps null: false
    end
    add_foreign_key :preferences, :users, column: :user_id, dependent: :destroy, :unique => true
    add_index :preferences, :user_id, unique: true
  end
end

в Rails 5 Вы можете сделать то же самое с более элегантной:

t.belongs_to :user, foreign_key: true, index: { unique: true }

это создаст ограничение внешнего ключа, а также уникальный индекс. Не забудьте добавить null: false если это требуемая ассоциация (звучит так же, как в случае исходного вопроса).

отметим, что belongs_to - это просто псевдоним для references.