Laravel 模型观察者和关系
Laravel Model Observers & Relations
我有一个 Member、Person 和 Address 模型。它们与一对一关系相关联。 Member 有一个 Person,Person 有一个 Address,Address 属于 Person,Person 属于 Member 等等
现在,我的地址也可以属于一个位置...产生 2 个可为空的列,person_id
& location_id
我在 Address model
上创建了一个观察者。当我删除会员时,如果设置了 location_id
,我希望保留地址。
public function deleting(Address $address)
{
if($address->location_id != null) {
$address->person_id = null;
$address->save();
return false;
} else {
return true;
}
}
奇怪的是当我使用... ->address()->delete();
... 它会删除人的地址,并且不会触发 Observer 函数。我必须先单独删除地址 $address->delete();
,现在 Observer 函数将触发。
我在想的另一个问题,如果反过来呢?删除设置为 'person_id'
的位置?
是否有更好的方法来处理删除(可以)属于 2 个不同模型的模型? (仅 OneToOne 关系)。
我在想也许我必须为 Member 和 Location 创建 2 个 Observer,然后将其中一个放到 Address 模型中?或者根本不使用观察者
编辑:
所以可能会出现一个人和一个地点可以有相同地址的情况。在这种情况下,'person_id' 和 'location_id' 在 Address 模型上都是 != null。
到目前为止,我已经可以使用 MemberController 上的所有功能。就我而言
public 函数 destroy( $id ) 只会软删除一个成员,并保持 Person 和 Address 不变。
我现在需要解决的就是强制删除,我已经想出了一些办法,但我不确定什么是好的方法。有点味道:P
当我这样删除会员时
$member->person()->delete();
$member->forceDelete();
这行得通。但我必须做 3 次删除? (包括地址)。
另外删除一个地址应该取决于location_id的存在,因为当一个地址也属于一个Location时,我希望保留该地址,而是将person_id设置为null。
我已经通过在地址模型上创建一个观察者来尝试这个,但是我面临着不知道一个成员或一个位置是否被删除的问题,所以我不确定应该是哪个'_id'检查是否为空。
我面临的另一个问题是当我删除 Member->relation()-> 方式时观察者函数不会触发。它似乎只在我单独删除地址时才起作用 $address->delete();
因此,我怀疑观察者是否是一个好方法,也许我应该在 Member/Location 控制器中进行。
/**
* Permanently remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function remove( $id )
{
$member = $this->model->onlyTrashed()->find( $id );
$address = $member->person->address;
if($address->location_id != null) {
$address->person_id == null;
$address->save();
} else {
$address->delete();
}
$member->person()->delete();
$member->forceDelete();
这行得通,甚至可能是保持愚蠢简单的情况?但我不确定在这里做这个 Address 的东西是否是一个好方法,只是想学习。
会员 | hasOne - 属于 |人 | hasOne - 属于 |地址 |属于 - hasOne |地点
当 运行 类似 $member->relation()->delete();
的时候你无法让你的观察者开火的原因是因为 $member->relation()
只是 return [=] 的一个实例14=]。当您在 Builder
上调用 delete()
时,它只会执行查询,而不会实际新建模型,这反过来意味着永远不会触发事件。要触发事件,您只需执行 $member->relation->delete()
;
如果我理解你的问题是正确的,那么你可以将 listener/observer 添加到 Person
模型,这将删除没有位置的地址或使 person_id
null
如果是:
protected static function boot()
{
parent::boot();
static::deleting(function (self $person) {
if (is_null($person->address->location_id)) {
$person->address->delete();
} else {
$person->address->person_id = null;
$person->address->save();
}
});
}
然后在您的 Member
模型中您可以添加另一个删除侦听器,该侦听器还检查模型是否正在被强制删除:
protected static function boot()
{
parent::boot();
static::deleting(function (self $member) {
if ($member->forceDeleting) {
$member->person->delete();
}
});
}
使用上面的 $member->delete()
不会删除人或地址,但是 $member->forceDelete()
会导致人和地址都被删除(但地址只有在不删除时才会被删除'也属于某个位置)。
希望对您有所帮助!
我有一个 Member、Person 和 Address 模型。它们与一对一关系相关联。 Member 有一个 Person,Person 有一个 Address,Address 属于 Person,Person 属于 Member 等等
现在,我的地址也可以属于一个位置...产生 2 个可为空的列,person_id
& location_id
我在 Address model
上创建了一个观察者。当我删除会员时,如果设置了 location_id
,我希望保留地址。
public function deleting(Address $address)
{
if($address->location_id != null) {
$address->person_id = null;
$address->save();
return false;
} else {
return true;
}
}
奇怪的是当我使用... ->address()->delete();
... 它会删除人的地址,并且不会触发 Observer 函数。我必须先单独删除地址 $address->delete();
,现在 Observer 函数将触发。
我在想的另一个问题,如果反过来呢?删除设置为 'person_id'
的位置?
是否有更好的方法来处理删除(可以)属于 2 个不同模型的模型? (仅 OneToOne 关系)。
我在想也许我必须为 Member 和 Location 创建 2 个 Observer,然后将其中一个放到 Address 模型中?或者根本不使用观察者
编辑:
所以可能会出现一个人和一个地点可以有相同地址的情况。在这种情况下,'person_id' 和 'location_id' 在 Address 模型上都是 != null。
到目前为止,我已经可以使用 MemberController 上的所有功能。就我而言 public 函数 destroy( $id ) 只会软删除一个成员,并保持 Person 和 Address 不变。
我现在需要解决的就是强制删除,我已经想出了一些办法,但我不确定什么是好的方法。有点味道:P 当我这样删除会员时
$member->person()->delete();
$member->forceDelete();
这行得通。但我必须做 3 次删除? (包括地址)。 另外删除一个地址应该取决于location_id的存在,因为当一个地址也属于一个Location时,我希望保留该地址,而是将person_id设置为null。
我已经通过在地址模型上创建一个观察者来尝试这个,但是我面临着不知道一个成员或一个位置是否被删除的问题,所以我不确定应该是哪个'_id'检查是否为空。
我面临的另一个问题是当我删除 Member->relation()-> 方式时观察者函数不会触发。它似乎只在我单独删除地址时才起作用 $address->delete(); 因此,我怀疑观察者是否是一个好方法,也许我应该在 Member/Location 控制器中进行。
/**
* Permanently remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function remove( $id )
{
$member = $this->model->onlyTrashed()->find( $id );
$address = $member->person->address;
if($address->location_id != null) {
$address->person_id == null;
$address->save();
} else {
$address->delete();
}
$member->person()->delete();
$member->forceDelete();
这行得通,甚至可能是保持愚蠢简单的情况?但我不确定在这里做这个 Address 的东西是否是一个好方法,只是想学习。
会员 | hasOne - 属于 |人 | hasOne - 属于 |地址 |属于 - hasOne |地点
当 运行 类似 $member->relation()->delete();
的时候你无法让你的观察者开火的原因是因为 $member->relation()
只是 return [=] 的一个实例14=]。当您在 Builder
上调用 delete()
时,它只会执行查询,而不会实际新建模型,这反过来意味着永远不会触发事件。要触发事件,您只需执行 $member->relation->delete()
;
如果我理解你的问题是正确的,那么你可以将 listener/observer 添加到 Person
模型,这将删除没有位置的地址或使 person_id
null
如果是:
protected static function boot()
{
parent::boot();
static::deleting(function (self $person) {
if (is_null($person->address->location_id)) {
$person->address->delete();
} else {
$person->address->person_id = null;
$person->address->save();
}
});
}
然后在您的 Member
模型中您可以添加另一个删除侦听器,该侦听器还检查模型是否正在被强制删除:
protected static function boot()
{
parent::boot();
static::deleting(function (self $member) {
if ($member->forceDeleting) {
$member->person->delete();
}
});
}
使用上面的 $member->delete()
不会删除人或地址,但是 $member->forceDelete()
会导致人和地址都被删除(但地址只有在不删除时才会被删除'也属于某个位置)。
希望对您有所帮助!