ガイドに従って、次のコマンドを実行しました。
rails g migration CreateSnippetsUsers snippet:belongs_to user:belongs_to
これにより、次の移行が作成されました。
class CreateSnippetsUsers < ActiveRecord::Migration[5.0]
def change
create_table :snippets_users do |t|
t.belongs_to :snippet, foreign_key: true
t.belongs_to :user, foreign_key: true
end
end
end
以前、 の代わりに を使った同じものを見たことがありますindex: true
。foreign_key: true
この 2 つの違いは何でしょうか?
ベストアンサー1
インデックス、外部キーそして外部キー制約これらはデータベース内で密接に関連した概念ですが、混同されたり誤解されたりすることがよくあります。
参考文献
宣言すると参照では、別のテーブルの値と一致する値を持つ列を含めるように指定しているだけです (Rails では、関連付けられたモデルをナビゲートするための便利なメソッドもいくつかあります)。次の例では、
create_table :appointments do |t|
t.references :student
end
テーブルappointments
には という名前の列があり、student_id
その値は学生の ID 値のプールに含まれる必要があります。
インデックス
参照を追加すると、その列を頻繁に使用する可能性が高いため、参照列を使用して検索速度を上げるようにデータベースに指示することもできます (おそらくそうすべきです)。これは オプションを使用して実行できますindex: true
(ちなみに、これはreference
Rails 5 以降の メソッドのデフォルト オプションです)。インデックスにはいくつかの欠点がありますが、主な欠点はメモリ消費量が大きいことです。
外部キー制約
これまで述べてきたように、reference column
と はforeign column
同義語です。しかし、参照列の値がすべき他のテーブルのものと一致するでしょうか?参照を宣言するだけでは、参照先のテーブルに一致する行が存在することを確認する責任があります。そうしないと、存在しない生徒の予約を作成するなど、無意味な操作が行われてしまいます。これは、データベースの整合性幸いなことに、より強力なレベルの整合性を保証するメカニズムがいくつかあります。これらのメカニズムは「データベース制約」このオプションforeign_key: true
が行うことは、まさにこの種の制約を参照列に追加し、参照先のテーブルに外部キー値が存在しないエントリを拒否することです。
データベースの整合性は複雑な作業であり、データベースが複雑になるほど困難さが増します。生徒を削除すると既存の予定もすべて破棄されるように、クラスでキーワードを使用するなど、他の種類の制約dependent: :destroy
も追加する必要があります。
いつものように、ここに RTFM リンクがあります:https://guides.rubyonrails.org/association_basics.html