#php #laravel #phpmyadmin #relationship #one-to-many
#php #laravel #phpmyadmin #отношение #один ко многим
Вопрос:
У меня есть 3 таблицы:
Пользователи
id
role
email
typable_id
typable_type
покупатели
id
name
address
avatar
email
residential_id
остаточные значения
id
name
city
state
И вот моя модель, которая показывает взаимосвязь
User.php
public function typable()
{
return $this->morphTo();
}
Buyer.php
public function residential()
{
return $this->belongsTo(Residential::class);
}
public function user()
{
return $this->morphMany(User::class, 'typable');
}
Residential.php
public function buyer()
{
return $this->hasMany(Buyer::class);
}
Если я хочу удалить жилое помещение, необходимо удалить всех покупателей из этого жилого помещения. То же, что и пользователи, которые также должны быть удалены при удалении покупателей. Как я могу это сделать? Это то, что находится внутри моего постоянного контроллера для функции уничтожения.
ResidentialController
public function destroy(Request $request)
{
$residentials = Residential::find($request->input('id'));
$residentials->id = $request->input('id');
$residentials->name = $request->input('name');
$residentials->delete($residentials);
return response()->json($residentials);
}
Я попытался поместить этот код для удаления покупателей (для пользователей, которых еще нет) внутри destroy(), но ничего не изменилось для удаления покупателей.
$buyers = Buyer::where('residential_id','=',$request->residential_id)->first();
$buyers->delete($buyers);
Хотя это код, который мне удалось выполнить, если я хочу удалить покупателей, пользователи тоже удаляются.
BuyerController
public function destroy(Request $request)
{
$users = User::where('email', '=', $request->email)->first();
$buyers = Buyer::find($request->input('id'));
$buyers->id = $request->input('id');
$buyers->name = $request->input('name');
$buyers->delete($buyers);
$users->delete($users);
return response()->json($buyers);
}
Я надеюсь, что есть кто-то, кто поможет и научит меня правильному способу.
Ответ №1:
Подход-1
вы можете переопределить функцию удаления для любой модели.
//Residential.php
public function delete()
{
$this->buyer->delete();
return parent::delete();
}
//Buyer.php
public function delete()
{
$this->user->delete();
return parent::delete();
}
Теперь, когда вы удаляете любую запись о проживании, цепочка сначала удалит любого связанного пользователя, а затем удалит покупателя и, наконец, удалит запись о проживании.
Подход-2
Вы можете использовать each()
метод, чтобы получить всех связанных покупателей, а затем получить всех связанных пользователей.
$residentials->buyer
->each(function ($b) {
$b->user->each(function ($u) {
$u->delete();
});
$b->delete();
});
$residentials->delete();
Комментарии:
1. Я использую второй подход, и он работает! Большое вам спасибо!!
Ответ №2:
Возможно, вы захотите зарегистрировать события модели, чтобы справиться с этим:
class Residential extends Model
{
// Lets use plural form for a HasMany relationship.
public function buyers()
{
return $this->hasMany(Buyer::class);
}
protected static function booted()
{
static::deleting(function ($user) {
// I am using Higher Order Message, check this out: https://laravel.com/docs/8.x/collections#higher-order-messages
$this->buyers->each->delete();
});
}
}
class Buyer extends Model
{
// Lets use the plural form for a MorpMany relationship.
public function users()
{
return $this->morphMany(User::class, 'typable');
}
protected static function booted()
{
static::deleting(function ($user) {
$this->users->each->delete();
});
}
}
И вам нужно удалить только один объект в вашем контроллере:
class ResidentialController
{
public function destroy(Request $request)
{
$residential = Residential::findOrFail($request->input('id'));
$residential->delete();
// The framework is gonna automatically convert this to a JSON object.
return $residential;
}
}
class BuyerController
{
public function destroy(Request $request)
{
$buyer = Buyer::findOrFail($request->input('id'));
$buyer->delete();
// The framework is gonna automatically convert this to a JSON object.
return $buyer;
}
}
Комментарии:
1. Вы могли бы сделать
$this->users()->delete()
, чтобы упростить запрос2. Хорошая мысль @KennyHorna. Это определенно работает в этом контексте. Но если пользовательская модель содержит дополнительные события, они не будут запущены. Итак, мой код немного лучше.
3. Тогда больше не нужно вводить какие-либо запросы в резидентный контроллер
destroy()
?4. О, запрос на удаление жилого помещения должен быть там, иначе как я могу его удалить, верно?
5. @IrdinaZulkeflee Я обновил свой ответ. Надеюсь, это отвечает на ваш вопрос.