J'ai mis en place les relations suivantes:
class Page {
public function comments() {
return $this->hasMany('Comment');
}
}
class Comment {
public function page() {
return $this->belongsTo('Page');
}
}
Assez standard de tourbière. Une page peut contenir plusieurs commentaires et un commentaire appartient à une seule page.
J'aimerais pouvoir créer une nouvelle page:
$page = new Page;
et un commentaire
$comment = new Comment;
et attachez le commentaire à la page, sans l'enregistrer
$page->comments->associate($comment);
J'ai essayé ce qui suit:
// These are for one-to-many from the MANY side (eg. $comment->page->associate...)
$page->comments->associate($comment); // Call to undefined method Illuminate\Database\Eloquent\Collection::associate()
$page->comments()->associate($comment); // Call to undefined method Illuminate\Database\Query\Builder::associate()
// These 2 are for many-to-many relations, so don't work
$page->comments->attach($comment); // Call to undefined method Illuminate\Database\Eloquent\Collection::attach()
$page->comments()->attach($comment); // Call to undefined method Illuminate\Database\Query\Builder::attach()
// These 2 will (if successful) save to the DB, which I don't want
$page->comments->save($comment); // Call to undefined method Illuminate\Database\Eloquent\Collection::save()
$page->comments()->save($comment); // Integrity constraint violation: 1048 Column 'page_id' cannot be null
La chose vraiment étrange est que faire le contraire (attacher la page au commentaire) fonctionne correctement:
$comment->page()->associate($page);
Les documents pertinents sont ici mais ils ne font aucune mention de l'attachement à l'un côté d'un à plusieurs. Est-ce même possible? (J'ai l'impression que ça devrait être)
Il semble que vous souhaitiez simplement ajouter le nouvel objet de commentaire à la collection de commentaires de la page - vous pouvez le faire facilement, en utilisant la méthode d'ajout de collection de base:
$page = new Page;
$comment = new Comment;
$page->comments->add($comment);
Vous ne pouvez pas le faire car il n'y a aucun identifiant à lier.
Vous devez donc d'abord enregistrer le parent ($page
) puis enregistrez le modèle enfant:
// $page is existing model, $comment don't need to be
$page->comments()->save($comment); // saves the comment
ou l'inverse, cette fois sans enregistrer:
// again $page exists, $comment don't need to
$comment->page()->associate($page); // doesn't save the comment yet
$comment->save();
selon Benubird, je voulais juste ajouter quelque chose alors que je suis tombé dessus aujourd'hui:
Vous pouvez appeler la méthode add sur une collection comme Benubird l'a indiqué. Pour tenir compte des préoccupations d'edpaaz (requête supplémentaire déclenchée), j'ai fait ceci:
$collection = $page->comments()->getEager(); // Will return the eager collection
$collection->add($comment) // Add comment to collection
Pour autant que je puisse voir, cela empêchera la requête supplémentaire car nous utilisons uniquement l'objet relation.
Dans mon cas, l'une des entités était persistante tandis que la première (dans votre page de cas) n'était pas (et à créer). Comme je devais traiter quelques choses et que je voulais gérer cela de manière objet, je voulais ajouter un objet entité persistant à un objet non persistant. Devrait aussi fonctionner avec les deux non persistants.
Merci Benubird de m'avoir pointé dans la bonne direction. J'espère que mon ajout aide quelqu'un comme il l'a fait pour moi.
Veuillez garder à l'esprit qu'il s'agit de mon premier post stackoverflow, veuillez donc laisser vos commentaires avec un peu de préoccupation.