Когда я удаляю строку, используя этот синтаксис:
$user->delete();
Есть ли способ привязать обратный вызов, чтобы он, например, делал это автоматически:
$this->photo()->delete();
Предпочтительно внутри модельного класса.
Я считаю, что это идеальный случай использования для событий 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.
Таким образом, в этом случае, если ваша таблица фотографий содержит ссылку на внешний ключ для пользователя, чем все, что вам нужно сделать, это удалить гостиницу, а очистка будет осуществляться базой данных, база данных удалит все записи фотографий из данных база.