Intereting Posts

Автоматическое удаление связанных строк в Laravel (Eloquent ORM)

Когда я удаляю строку, используя этот синтаксис:

$user->delete(); 

Есть ли способ привязать обратный вызов, чтобы он, например, делал это автоматически:

 $this->photo()->delete(); 

Предпочтительно внутри модельного класса.

Related of "Автоматическое удаление связанных строк в Laravel (Eloquent ORM)"

Я считаю, что это идеальный случай использования для событий Eloquent ( http://laravel.com/docs/eloquent#model-events ). Вы можете использовать событие «удаление», чтобы выполнить очистку:

 class User extends Eloquent { public function photos() { return $this->has_many('Photo'); } // this is a recommended way to declare event handlers protected static function boot() { parent::boot(); static::deleting(function($user) { // before delete() method call this $user->photos()->delete(); // do the rest of the cleanup... }); } } 

Вероятно, вы также должны положить все это в транзакцию, чтобы обеспечить ссылочную целостность.

Вы можете установить это в своих миграциях:

$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

Источник: http://laravel.com/docs/5.1/migrations#foreign-key-constraints

Вы также можете указать желаемое действие для свойств «on delete» и «on update» ограничения:

 $table->foreign('user_id') ->references('id')->on('users') ->onDelete('cascade'); 

Примечание . Этот ответ был написан для Laravel 3 . Таким образом, может быть или не удастся хорошо работать в более поздней версии Laravel.

Вы можете удалить все связанные фотографии перед удалением пользователя.

 <?php class User extends Eloquent { public function photos() { return $this->has_many('Photo'); } public function delete() { // delete all related photos $this->photos()->delete(); // as suggested by Dirk in comment, // it's an uglier alternative, but faster // Photo::where("user_id", $this->id)->delete() // delete the user return parent::delete(); } } 

Надеюсь, поможет.

Отношение в модели пользователя:

 public function photos() { return $this->hasMany('Photo'); } 

Удалить запись и связать:

 $user = User::find($id); // delete related $user->photos()->delete(); $user->delete(); 

Начиная с Laravel 5.2, в документации указано, что эти виды обработчиков событий должны быть зарегистрированы в AppServiceProvider:

 <?php class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { User::deleting(function ($user) { $user->photos()->delete(); }); } 

Я даже предполагаю, что они перемещают их в отдельные классы вместо закрытия для лучшей структуры приложения.

Или вы можете сделать это, если хотите, просто еще один вариант:

 try { DB::connection()->pdo->beginTransaction(); $photos = Photo::where('user_id', '=', $user_id)->delete(); // Delete all photos for user $user = Geofence::where('id', '=', $user_id)->delete(); // Delete users DB::connection()->pdo->commit(); }catch(\Laravel\Database\Exception $e) { DB::connection()->pdo->rollBack(); Log::exception($e); } 

Обратите внимание, что если вы не используете соединение по умолчанию larvel db, вам необходимо сделать следующее:

 DB::connection('connection_name')->pdo->beginTransaction(); DB::connection('connection_name')->pdo->commit(); DB::connection('connection_name')->pdo->rollBack(); 

В моем случае это было довольно просто, потому что мои таблицы базы данных – InnoDB с внешними ключами с Cascade on Delete.

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