John Aldrin
John Aldrin

Reputation: 163

Eloquent: Model relationship without saving to DB

Say I have two Models: User and Task

Their relationship is as follows: User can have many tasks (belongsToMany) Task can have many users (belongsToMany)

$user = new User();
$task = new Task();

Normally, I'd do something like this: $user->tasks->attach($task)

But the problem is the User and Task is not persisted in the database. So if I run the last code above, I'll get an integrity constraint because these models have no id.

I have looked into the documentation and I found at that there is a method associate() but this requires either one of the model that has an id (saved in the database).

Is there any way I could attach a Model to another Model without them having persisted in the database?

Upvotes: 3

Views: 5635

Answers (4)

SameOldNick
SameOldNick

Reputation: 2447

Another way is by saving/attaching the models when the parent model fires the 'saved' event:

<?php

$parent = new ParentModel();

$children = [
  new ChildModel(['name' => 'First child']),
  new ChildModel(['name' => 'Second child']),
];

// $parent doesn't need to be referenced since it's an object.
ParentModel::saved(function (ParentModel $model) use ($parent, $children) {
  // The comparison is important because this will be called when any ParentModel is saved.
  if ($model === $parent) {
    $model->items()->saveMany($children);
  }
});

Upvotes: 0

Linus
Linus

Reputation: 51

You can use the make method on the relation itself to create a relation model instance without saving. The make method is not part of the docs but part of the Laravel API Docs.

Example:

$task = $user->tasks()->make($attributes);

If you would like to persist $task afterwads you can save the task with the save method.

$task->save();

Source:

make(array $attributes = [])

Create and return an un-saved instance of the related model.

https://laravel.com/api/11.x/Illuminate/Database/Eloquent/Relations/HasMany.html

Upvotes: 0

Arun Ganessh
Arun Ganessh

Reputation: 91

I guess you could call setRelation manually.

$model->setRelation('child', $childInstance);

eLSE

You create a new model simply by instantiating it:

$model = new Model;

You can then save it to the database at a later stage:

$model->save();

Upvotes: 8

Mina Abadir
Mina Abadir

Reputation: 2981

The model in Laravel is nothing but a normal class. So instantiating it only would not persist to DB. You should persist to DB by saving the model:

This can be done by running save() as below:

$user->save();
$task->save();

$user->tasks()->attach($task->id);

It's important to note that the it's $user->tasks()->attach() and not $user->tasks->attach()

Upvotes: -1

Related Questions