2016-03-02 24 views
7

Ho una relazione molti a molti tra due modelli, utenti e ruoli. C'è una differenza tra salvare una relazione usando il metodo save() e usando il metodo attach()?Laravel 5 - Molti a molti - Collega o salva

$user->roles()->save($role, ['expires' => $expires]); //using save 
$user->roles()->attach($roleId, ['expires' => $expires]);// using attach 

I due equivalenti? Personalmente non vedo la differenza. Pensieri?

risposta

7

Questo è il snippet di codice per il metodo save(). Vedrai che alla fine chiama attach().

/** 
* Save a new model and attach it to the parent model. 
* 
* @param \Illuminate\Database\Eloquent\Model $model 
* @param array $joining 
* @param bool $touch 
* @return \Illuminate\Database\Eloquent\Model 
*/ 
public function save(Model $model, array $joining = [], $touch = true) 
{ 
    $model->save(['touch' => false]); 
    $this->attach($model->getKey(), $joining, $touch); 
    return $model; 
} 

Una grande differenza è che salva anche il modello che si sta passando ad esso. In altre parole, puoi essenzialmente creare un nuovo ruolo (o addirittura aggiornare quello vecchio) mentre lo colleghi anche all'utente. Ad esempio:

// Get the user 
$user = User::first(); 

// Instantiate a new role 
$role = new Role($attributes); 

// Creates the role/persists it into the database and attaches this role to the user 
$user->roles()->save($role, ['expires' => $expires]); 
+0

Se si salva() un nuovo ruolo per un utente che non esiste nella tabella dei ruoli, creerà un nuovo record di ruolo nel database dei ruoli? Quindi, fondamentalmente l'uso di save() non ci darà mai un errore, ma l'uso di un attach() potrebbe darci un errore di chiave esterna se il ruolo non esiste? – alaboudi

+0

@alaboudi In un certo senso sì, ma credo che 'attach()' non crei un errore neanche se passi una nuova istanza di un modello. Semplicemente non collegherà nulla perché il modello non esiste nel database. Tuttavia, 'save()' farà il passo in più per salvarlo prima nel database se non esiste o aggiornarlo se deve essere aggiornato prima di collegarlo. –

+1

Risposta fantastica – alaboudi