2014-07-11 13 views
5

Ho un problema con una relazione Eloquent morphOne in cui sta creando nuove voci anziché aggiornare quella già esistente.La relazione morphoune eloquente non limita una relazione

Fondamentalmente ho un certo numero di modelli (per esempio, diciamo Person e Building) che entrambi hanno bisogno di un luogo, così ho creato un modello di Location:

class Location extends Eloquent { 

    public function locationable() 
    { 
     return $this->morphTo(); 
    } 

} 

Poi in altri miei modelli Ho questo :

class Person extends Eloquent { 

    // ... 

    /** 
    * Get the person's location 
    * 
    * @return Location 
    */ 
    public function location() 
    { 
     return $this->morphOne('Location', 'locationable'); 
    } 

    // ... 
class Building extends Eloquent { 

    // ... 

    /** 
    * Get the building's location 
    * 
    * @return Location 
    */ 
    public function location() 
    { 
     return $this->morphOne('Location', 'locationable'); 
    } 

    // ... 

Quando eseguo il seguente codice di prova, si cre va bene alla voce di posizione, ma se lo ripeto, crea più voci.

$person = Person::first(); 

$loc = new Location; 

$loc->lat = "123"; 
$loc->lng = "321"; 

$person->location()->save($loc); 

Sto facendo qualcosa di sbagliato qui? Mi sarei aspettato morphOne per vincolare questo per una voce per tipo, quindi l'ultima voce nella tabella sottostante non dovrebbe esistere:

+---------------------+--------------------------+ 
| locationable_id | locationable_type  | 
+---------------------+--------------------------+ 
| 2     | Building    | 
| 3     | Building    | 
| 2     | Person     | 
| 2     | Building    | 
+---------------------+--------------------------+ 
+1

No, non stai sbagliando. È solo come funziona. Le relazioni polimorfiche sono buone per cose facili, ma più vai avanti, più bug trovi. –

+0

Quindi suggerisci di evitarli ovunque possibile? Non ha senso per me fare qualsiasi altra cosa, ma creare una relazione polimorfica. 1) Qualcuno suggerisce di fare un semplice controllo if else per vedere se 'orderable_type' è vuoto quindi creare, altrimenti aggiornare, qual è la tua opinione su questo? 2) https://i.imgur.com/gPmh1OK.png Opinione su questo? Mi piacerebbe sentirlo. Grazie amico. – Pavan

risposta

2

In realtà, chiamando

$loc = new Location; 

si sono, per definizione, creando una nuova posizione!

Calling

$person->location()->save($loc); 

non aiuta.

Se si desidera aggiornare una posizione, è necessario trovare la posizione, aggiornare i valori e quindi salvarlo. Indipendentemente dal modello principale:

$person = Person::first(); 

$loc = $person->location; 

$loc->lat = "123"; 
$loc->lng = "321"; 

$loc->save(); 

Fatto.

1

Forse sono in ritardo per la festa, ma questo ha funzionato per me!

# Do we have location already? 
if($person->location) { 
    return $person->location()->update($location); 
} 
return $person->location()->create($location); 
1

Sulla base delle mie esperienze molto attuali, questa soluzione dovrebbe essere opere

creazione o sostituire il vecchio dalla nuova istanza Località modello:

$person = Person::first(); 

$loc = new Location; 

$loc->lat = "123"; 
$loc->lng = "321"; 

$loc->save(); 
$person->location()->associate($loc); 
$person->save(); 

Aggiornamento:

$person = Person::first(); 

$person->location->lat = "123"; 
$person->location->lng = "321"; 

$person->location->save(); 
$person->save(); 

I abbiamo trascorso molti giorni per scoprire questa soluzione. Spero che lo documenterebbero molto meglio ufficialmente.

Problemi correlati