The push method feels as though it should be able to save any new relations added to the model. However it can't as the foreign id isn't set.
See the following code as an example:
$user = new User(['name' => 'Mike']);
$post = new Post(['title' => 'Push is broken']);
$user->posts->add($$post);
$user->push();
I have faced this issue many times before, I'll try to find a solution for this.
You are just adding a model to a loaded collection of the relationship result. You should use one of these method to insert related models: http://laravel.com/docs/5.1/eloquent-relationships#inserting-related-models
@lukasgeiter yes, but in that case it'll probably throw an error as well since this is a new user. I think the method push should do the all the work.
You could probably do something like $user->setRelation('posts', collect($post)); $user->push();
Also I don't see why you can't just save the user before inserting relationships?
@lukasgeiter of course you can, but it's not intuitive and you could delegate that to the ORM.
Give me a couple of days and I'll present a possible solution for this "issue".
I came here to post this exact issue.
@lucasgeiter I have a model where a number of mutators need to update or create a related model. The related model requires multiple fields to be set before validation will allow it to be saved to the database, so either the validation or mutators have to go.
@sileence Have you made any progress on a solution? Is there any assistance I could provide?
@sileence Did you ever find a clean solution for this?
@barryvdh yes, first you need to save the belongsTo relations, then the main model, and finally the hasMany relations.
I set a reminder to work on this when I get home (about 4 hours from now).
Ok working on this again @barryvdh
narrowing the problem:
https://github.com/sileence/eloquent_push_tests/blob/master/tests/EloquentPushTest.php
The unit tests pass because they don't have FK as these integration tests do.
@barryvdh the code is "primitive" but the tests are passing, I can refactor and PR later:
https://github.com/sileence/eloquent_push_tests/blob/master/app/Model.php
https://github.com/sileence/eloquent_push_tests/blob/master/tests/EloquentPushTest.php
cc @taylorotwell
Thanks, I also tried something and got something similar. Combined them with your result with a few tweaks:
$user->posts = [..] on a new model)save() method instead of the keysSee https://gist.github.com/barryvdh/f963f5c67d5cfc23357f1a81b3aad56a
Can do something like this:
$user = new User;
$user->name = 'Barry';
$user->email = str_random();
$user->password = str_random();
$post = new Post;
$post->title = 'Test 1';
$post->body = 'Lorem ipsum';
$user->posts[] = $post;
$user->posts[] = [
'title' => 'Test 2',
'body' => 'from array',
];
$user->pushAll();
The only thing which could be 'breaking' is the automatic changing of attributes -> relations, so might make an extra method or add a better check?
Most helpful comment
Thanks, I also tried something and got something similar. Combined them with your result with a few tweaks:
$user->posts = [..]on a new model)save()method instead of the keysSee https://gist.github.com/barryvdh/f963f5c67d5cfc23357f1a81b3aad56a
Can do something like this:
The only thing which could be 'breaking' is the automatic changing of attributes -> relations, so might make an extra method or add a better check?