Railsでカスケード削除を設定する方法:データベースの外部キー制約とdependentオプション
Railsでカスケード削除を設定する方法
データベースの外部キー制約を使用する
この方法は、データベースレベルで外部キー制約を設定することで、参照元テーブルのレコードが削除された際に、参照している子テーブルのレコードも自動的に削除されるようにします。
手順
- マイグレーションファイルを作成します。
rails generate migration AddForeignKeyToOrderDetails
- 作成したマイグレーションファイルを開き、以下のコードを追加します。
class AddForeignKeyToOrderDetails < ActiveRecord::Migration[5.2]
def change
add_foreign_key :order_details, :orders, on_delete: :cascade
end
end
rails db:migrate
ポイント
- 上記の例では、
order_details
テーブルがorders
テーブルを参照しているという関係性になっています。
dependent オプションを使用する
この方法は、dependent
オプションを使用して、親レコードが削除された際に、関連する子レコードをどのように処理するかを指定します。
- 親モデルのファイルを開き、
has_many
アソシエーションにdependent
オプションを追加します。
class Order < ApplicationRecord
has_many :order_details, dependent: :destroy
end
- その他にも、
dependent: :nullify
オプションなどを指定することで、子レコードの外部キーカラムをNULL
に設定したりすることができます。
Railsでカスケード削除を設定するには、データベースの外部キー制約を使用する方法と、dependent
オプションを使用する方法の2つがあります。 どちらの方法もメリットとデメリットがあるため、状況に合わせて使い分けることが重要です。
データベースの外部キー制約を使用する
# マイグレーションファイル
class AddForeignKeyToOrderDetails < ActiveRecord::Migration[5.2]
def change
add_foreign_key :order_details, :orders, on_delete: :cascade
end
end
# 親モデル (orders.rb)
class Order < ApplicationRecord
belongs_to :user
has_many :order_details
end
# 子モデル (order_details.rb)
class OrderDetail < ApplicationRecord
belongs_to :order
end
dependent オプションを使用する
# 親モデル (orders.rb)
class Order < ApplicationRecord
belongs_to :user
has_many :order_details, dependent: :destroy
end
# 子モデル (order_details.rb)
class OrderDetail < ApplicationRecord
belongs_to :order
end
動作確認
- Railsアプリケーションを起動します。
- 親レコードを作成します。
- 子レコードが削除されていることを確認します。
注意点
- カスケード削除を使用する場合は、誤ってレコードが削除されないように注意が必要です。
- データベースの外部キー制約を使用する場合は、マイグレーションファイルの記述に誤りがないことを確認する必要があります。
カスケード削除を設定するその他の方法
コールバックを使用して、親レコードが削除される前に、関連する子レコードを削除することができます。
# 親モデル (orders.rb)
class Order < ApplicationRecord
belongs_to :user
has_many :order_details
before_destroy :delete_order_details
private
def delete_order_details
order_details.destroy_all
end
end
手動で削除する
親レコードと子レコードを関連付けるテーブルに cascade_delete
というカラムを追加し、そこに true
または false
を設定することで、カスケード削除を制御することができます。
# テーブル定義
create_table :orders do |t|
t.string :name
t.boolean :cascade_delete
end
# 親モデル (orders.rb)
class Order < ApplicationRecord
belongs_to :user
has_many :order_details
def destroy
if cascade_delete
order_details.destroy_all
end
super
end
end
プラグインを使用する
acts_as_paranoid
などのプラグインを使用することで、カスケード削除を含む、さまざまな機能を追加することができます。
カスケード削除を設定する方法はいくつかありますが、それぞれメリットとデメリットがあります。 状況に合わせて最適な方法を選択してください。
ruby-on-rails ruby database