app/controllers/test_controller.rb
class TestController < ApplicationController
def index
Employee.where('id <= 10').delete_all
@test = Employee.count
end
end
説明
\n1delete_allメソッドの基本
\nモデルのデータをまとめて削除するには、delete_allメソッドを使用します:
\n
\n \n モデル.delete_all\n
このメソッドを実行すると、該当するモデルのすべてのレコードが一度に削除されます。
\n \n\n
\n\n\n\n Employee.delete_all # Employeeテーブルの全レコードを削除\n
2条件付きデータ削除
\n特定の条件に一致するデータだけを削除したい場合は、whereメソッドと組み合わせて使用します:
\n
\n \n Employee.where("id <= ?", 20).delete_all\n 上の例では、Employeeモデルのidが20以下のデータを削除しています。
\n \n他の条件指定の例:
\n \n\n
\n\n\n\n # 退職済みの従業員を削除\nEmployee.where(status: "退職").delete_all\n\n# 特定の部署の従業員を削除\nEmployee.where(department: "営業部").delete_all\n\n# 1年以上更新されていないレコードを削除\nEmployee.where("updated_at < ?", 1.year.ago).delete_all\n 3delete_allとdestroy_allの違い
\nRailsには似たような機能を持つdestroy_allメソッドもありますが、重要な違いがあります:
ポイント
\n delete_all:
\n- \n
- SQLの
DELETE文を直接実行するため高速 \n - モデルのコールバックは実行されない \n
- 関連するレコードは自動削除されない(
dependent: :destroyは無視される) \n
destroy_all:
\n- \n
- 各レコードに対して
destroyメソッドを呼び出すため遅い \n - モデルのコールバックが実行される \n
- 関連するレコードも適切に処理される(
dependent: :destroyが機能する) \n
適切なメソッドの選択:
\n- \n
- 単純にデータを削除するだけなら
delete_allが高速 \n - 関連するレコードも削除したい場合や、コールバックが必要な場合は
destroy_allを使用 \n
4delete_allの戻り値
\ndelete_allメソッドは、削除されたレコードの数を整数で返します:
\n
\n \n deleted_count = Employee.where(department: "営業部").delete_all\nputs "#{deleted_count}件のレコードが削除されました"\n この戻り値を使用して、削除処理の結果をユーザーに通知したり、ログに記録したりすることができます。
\n\n\n\n5実践的な使用例
\nコントローラーでの実際の使用例:
\n \n\n
\n\n\nclass EmployeesController < ApplicationController\n def bulk_delete\n if params[:department].present?\n # 特定の部署の従業員を削除\n count = Employee.where(department: params[:department]).delete_all\n flash[:notice] = "#{count}人の#{params[:department]}の従業員を削除しました"\n elsif params[:before_date].present?\n # 特定の日付より前に登録された従業員を削除\n date = Date.parse(params[:before_date])\n count = Employee.where("created_at < ?", date).delete_all\n flash[:notice] = "#{date.strftime('%Y年%m月%d日')}より前に登録された#{count}人の従業員を削除しました"\n else\n flash[:alert] = "削除条件が指定されていません"\n end\n \n redirect_to employees_path\n end\n \n def clear_inactive\n # 90日以上ログインしていないユーザーを削除\n count = Employee.where("last_login_at < ?", 90.days.ago).delete_all\n \n respond_to do |format|\n format.html {\n flash[:notice] = "#{count}人の非アクティブユーザーを削除しました"\n redirect_to admin_dashboard_path\n }\n format.json {\n render json: { deleted_count: count, status: "success" }\n }\n end\n end\nend\n ポイント
\n 注意事項:
\n- \n
delete_allは元に戻せない操作なので、実行前にバックアップを取ることをお勧めします。 \n - 本番環境で大量のデータを削除する場合は、データベースのパフォーマンスに影響する可能性があるため、オフピーク時に実行することを検討してください。 \n
- 関連データの整合性を保つため、外部キー制約がある場合は特に注意が必要です。 \n
- 大規模なデータ削除はトランザクション内で行うとより安全です。 \n