Laravel Model Observers&关系

时间:2017-06-30 18:24:49

标签: laravel one-to-one observers

我有会员,人员和地址模型。它们与一对一关系相关联。会员有一个人,人有一个地址,地址属于人,人属于会员等。

现在,我的地址也可以属于一个位置...导致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关系)。

我想也许我必须为会员和位置制作2个观察者,然后将其放在地址模型上?或者根本不使用观察员

修改

因此,可能会出现一个人和一个位置可以拥有相同地址的情况。在这种情况下,'person_id'和&地址模型上的'location_id'是!= null。

到目前为止,我已经在MemberController上运行了所有函数。就我而言 public function destroy($ id)只会对一个成员进行softdelete,并保持Person和Address不受影响。

现在我需要解决的是forceDeleting,我已经能够提出一些东西,但我不确定什么是好方法。有点气味:P 当我删除像这样的会员时

$member->person()->delete();
$member->forceDelete();

这样可行。但我将不得不做3次删除? (包括地址)。 删除地址也应该取决于是否存在location_id,因为当一个地址也属于一个Location时,我希望保留该地址,而是将person_id设置为null。

我通过在地址模型上建立一个观察者来尝试这个,但是我面临的问题是不知道会员或位置是否被删除,所以我不确定应该检查哪个'_id'是否为空。

我面临的另一个问题是当我删除Member-> relation() - >时,观察者功能不会触发。办法。它似乎只在我单独删除地址时有效$ address-> delete(); 因为这是我怀疑观察者是否是一个好方法,也许我应该在会员/位置控制器。

/**
 * 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();

这样可以工作,甚至可以保持简单愚蠢的情况吗?但我不确定在这里做这个地址的东西是一个好方法,只是想学习。

会员| hasOne - belongsTo |人| hasOne - belongsTo |地址| belongsTo - hasOne |位置

1 个答案:

答案 0 :(得分:1)

在运行$member->relation()->delete();之类的内容时,您无法让观察者触发的原因是因为$member->relation()只会返回Builder的实例。当您在delete()上调用Builder时,它将只执行查询,并且实际上不会新建模型,这反过来意味着事件永远不会被触发。要使事件发生,您只需执行$member->relation->delete();

即可

如果我理解您的问题是正确的,那么您可以向Person模型添加一个监听器/观察者,该模型将删除没有位置的地址或制作person_id { {1}}如果有:

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(); } }); } 模型中,您可以添加另一个删除侦听器,该侦听器还会检查模型是否为forceDeleted:

Member

使用上述protected static function boot() { parent::boot(); static::deleting(function (self $member) { if ($member->forceDeleting) { $member->person->delete(); } }); } 不会删除此人或地址,但$member->delete()会导致人员和地址被删除(但只有在地址不被删除时才会被删除也属于一个地方)。

希望这有帮助!