Reputation: 7235
I have Question
and Answer
models. The Question hasMany Answers. Following commands run in the php artisan tinker
mode invoke a database query for no apparent reason:
$q = new Question;
$q->answers[] = new Answer; // invokes the below query
// the executed query
select * from `answers` where `answers`.`question_id` is null and `answers`.`question_id` is not null
As you see, there is no need for database call whatsoever. How can I prevent it?
Upvotes: 1
Views: 176
Reputation: 25404
When you do $q->answers
, Laravel tries to load all of the answers on the question object - regardless of whether they exist or not.
Any time you access a relationship on a model instance, you can either call it like answers()
and get a query builder back, or you can call it like answers
without parentheses and Laravel will fetch a collection for you based on the relationship.
You can prevent it easily by doing this:
$q = new Question;
$a = new Answer;
And then, when you're ready to save them, associate them with each other. In its simplest form, that looks like this:
$q->save();
$q->answers()->save($answer);
Upvotes: 3
Reputation: 3288
It's doing that because you're assigning it to the Question
object. It wants to see if you're adding an extant record reference. All Laravel Eloquent models contain magic methods for properties, and trying to use them as temporary data storage is a really bad idea unless you've defined a property on them ahead of time for that specific purpose.
Just use a regular array instead and then associate them after the models have been prepared.
Documentation on one-to-many relationships:
https://laravel.com/docs/5.1/eloquent-relationships#one-to-many
Upvotes: 1