2017-06-30 2 views
0

J'ai un modèle Membre, Personne et Adresse. Ils sont connectés avec les relations One to One. Membre dispose d'une personne, personne a une adresse, adresse appartient à personne, et personne appartient Membre etc.Laravel Observateurs et modèles de modèles

Maintenant, mon adresse peut aussi belongTo un emplacement ... Entraînant 2 colums nullables, person_id & location_id

J'ai créé un observateur sur le Address model. Lorsque je supprime un membre, je souhaite que l'adresse soit conservée, si le location_id est défini.

public function deleting(Address $address) 
{ 
    if($address->location_id != null) { 
     $address->person_id = null; 
     $address->save(); 
     return false; 
    } else { 
     return true; 
    } 
} 

chose étrange est quand je l'utilise ... ->address()->delete(); ... Il supprimera l'adresse de la personne et le Observerfunction ne se déclenche pas. Je dois d'abord supprimer l'adresse séparément $address->delete();, et maintenant la fonction Observer se déclenchera. Un autre problème auquel je pensais, et si c'était l'inverse? Suppression d'un emplacement avec l'ensemble 'person_id'?

Existe-t-il un meilleur moyen de gérer la suppression d'un modèle auquel (peut) appartenir à 2 modèles différents? (Seules les relations OneToOne).

Je pensais peut-être que je devais faire 2 observateurs, pour le membre et l'emplacement, et laisser tomber celui sur le modèle d'adresse? Ou pas utiliser des observateurs du tout

EDIT:

Ainsi, la situation peut se produire qu'une personne et un emplacement peuvent avoir la même adresse. Dans ce cas, 'person_id' & 'location_id' est! = Null sur le modèle Adresse.

Jusqu'ici j'ai toutes les fonctions sur le MemberController fonctionnant. Dans mon cas public function destroy ($ id) ne fera que supprimer un membre de softdelete, et garder la personne et l'adresse intacte. Tout ce que j'ai besoin de réparer maintenant est forceDeleting, j'ai été capable de trouver des trucs, mais je ne suis pas sûr de ce qui est un bon moyen. Quelque chose sent: P Lorsque je supprime un membre comme celui-ci

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

Cela fonctionnerait. Mais je vais devoir faire 3 suppressions? (y compris l'adresse). La suppression d'une adresse doit également dépendre de la présence d'un ID de position, car lorsqu'une adresse appartient également à un emplacement, je souhaite que l'adresse soit conservée et définisse à la place la valeur person_id sur null. J'ai essayé ceci en faisant un observateur sur le modèle d'adresse, mais avec ceci je suis confronté au problème de ne pas savoir si un membre ou un emplacement est supprimé, et donc je ne suis pas sûr que '_id' devrait être vérifié pour être nul ou pas.

Un autre problème auquel je fais face est la fonction d'observateur qui ne se déclenche pas lorsque je supprime la méthode Member-> relation() ->. Cela ne semble fonctionner que lorsque je supprime l'adresse séparément $ address-> delete(); pour cette raison Im doutant si l'observateur est même un bon moyen, et peut-être que je devrais le faire dans le contrôleur de membre/emplacement.

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

Cela fonctionnerait, peut-être même un cas de le garder stupide simple? Mais je ne suis pas sûr si faire ce truc d'adresse ici est un bon moyen, juste essayer d'apprendre.

Membre | hasOne - appartient à | Personne | hasOne - appartient à | Adresse | appartient à - hasOne | Emplacement

+0

Vous m'avez perdu un peu. Pourriez-vous résumer exactement ce que vous recherchez et aussi ce que vous faites ou ne voulez pas faire? –

+0

J'ai édité ma question;) sry –

Répondre

1

La raison pour laquelle vous n'êtes pas en mesure d'obtenir vos observateurs à feu lors de l'exécution quelque chose comme $member->relation()->delete(); est parce que $member->relation() va simplement retourner une instance de Builder. Lorsque vous appelez le delete() sur Builder, il exécutera simplement la requête et n'effectuera pas la mise à jour d'un modèle, ce qui signifie qu'un événement ne sera jamais déclenché. Pour déclencher les événements, vous pouvez simplement faire $member->relation->delete();

Si je vous comprends, vous êtes la question pourrait bien alors ajouter un écouteur/observateur au modèle Person qui supprimera l'adresse qui ne dispose pas d'un endroit ou faire la person_idnull si elle fait:

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(); 
     } 

    }); 
} 

Ensuite, dans votre modèle Member vous pouvez ajouter un autre écouteur qui vérifie également la suppression si le modèle est forceDeleted:

protected static function boot() 
{ 
    parent::boot(); 

    static::deleting(function (self $member) { 

     if ($member->forceDeleting) { 
      $member->person->delete(); 
     } 
    }); 
} 

Utilisation duci-dessusne supprimera pas la personne ou l'adresse, cependant, $member->forceDelete() entraînera la suppression de la personne et de l'adresse (mais l'adresse ne sera supprimée que si elle n'appartient pas à un emplacement).

Espérons que cela aide!

+0

Hmm J'aime la façon dont vous le gardez dans les modèles, afin que les autres ne doivent pas regarder partout .. Et il gardera ma fonction de suppression à l'intérieur du membre court ... Je pense que je vais juste commenter le MemberController, en disant qu'il va aussi supprimer les modèles liés, à moins que ... Je suppose que faire cette vérification nulle dans le modèle Person, a plus de sens que de le faire dans le contrôleur Member ... Je pense J'ai déjà vu quelque chose comme ça, que faire de parent :: boot aussi? –

+0

Oui, vous avez absolument raison à propos de 'parent :: boot();'! Haha, désolé j'ai complètement manqué ça. –