Exercise 2: Application-Level vs. Database-Level Protection — Possible Solution ==================================================================== WHERE RAILS' dependent: :restrict_with_error OPERATES ------------------------------ Per this chapter, dependent: :restrict_with_error is implemented as an ActiveRecord callback. When destroy is called on a page, Rails checks in application code whether that page has any children, and if so, adds an error and aborts the operation before any DELETE statement is ever sent to the database. WHERE LARAVEL'S restrictOnDelete() OPERATES ------------------------------ Per this chapter, Laravel's restrictOnDelete() is a genuine database schema constraint, enforced by the database engine itself. It doesn't rely on Eloquent's own code running at all - it protects the row regardless of how the delete is attempted. WHY THE DIFFERENCE MATTERS ------------------------------ Per this chapter, because Rails' own check lives entirely in application code, a raw SQL DELETE statement that bypasses ActiveRecord entirely would skip that check completely. Laravel's database-level constraint could never be bypassed that way, since the database itself refuses the operation no matter what issued the delete. This puts Rails' own protection in the same general category as Django's own ORM-level PROTECT check, genuinely different from Laravel's database-enforced approach - though MySQL's own default foreign-key behavior still provides a real, if less friendly, backstop for Rails. WHY THIS WORKS AS AN ANSWER ------------------------------ It correctly identifies Rails' dependent: :restrict_with_error as an application-level ActiveRecord callback and Laravel's restrictOnDelete() as a database-level schema constraint, and correctly explains the practical consequence of that difference - a raw SQL delete could bypass Rails' check but not Laravel's.