Reputation: 668
I've got a hasMany relationship defined this way, in a Command
Eloquent model:
public function rows()
{
return $this->hasMany('\Acme\Models\Row')
}
In my case, rows can be linked to Commands, or not. So my Row
migration file contains a nullable foreign key:
$table->integer('command_id')->unsigned()->nullable()->index();
$table->foreign('command_id')->references('id')->on('commands')->onDelete('set null');
Nothing really crazy.
I realize thought that if I instantiate a new Command
object and call $command->rows
, instead of an empty Collection, I get all the rows with a null command_id
.
This is perfectly explained by the SQL generated by this $command->rows
call:
select * from `rows` where `rows`.`command_id` is null
I think it's strange that Laravel choose to consider valid a null foreign key... What do you think: is this a bug? Am I missing something? What could be the best way to prevent this behavior?
Thanks.
Upvotes: 3
Views: 951
Reputation: 81187
2 ways of handling this:
1 In order to prevent that behaviour, with your current setup, you need to add not null
clause on the relation definition:
public function rows()
{
return $this->hasMany('\Acme\Models\Row')->whereNotNull('rows.command_id');
}
2 You can also change your schema, so the foreign key is not nullable, but Rows
without Command
will have 0
value there.
Now, I think this is correct behaviour by all means. You are trying to fetch something, given null
as prerequisite, so it finds those rows. This is unexpected in terms of business logic, but definitely not wrong.
Not mentioning that I can't think, why you would like to call relation on newly instantiated model, that clearly doesn't have any. Unless it's just curiosity.
Upvotes: 3