Is it possible to replace null with an empty array when no relation is found?
E.g. The customer has contacts and contracts but one of the contract has no web.
$customers = Customer::with('contacts', 'contracts.web')
->orderBy('company')->orderBy('prename')->get();
The result would be as following...
2 => array:21 [
"id" => 1
"contacts" => array:2 [
0 => array:12 [
"id" => 1
"customer_id" => 1
]
1 => array:12 [
"id" => 2
"customer_id" => 1
]
]
"contracts" => array:2 [
0 => array:9 [
"id" => 1
"customer_id" => 1
"web" => array:7 [
"id" => 1
"contract_id" => 1
]
]
1 => array:9 [
"id" => 2
"customer_id" => 1
"web" => null // should be replaced with []
]
]
]
As I read in the docs (Constraining Eager Loads), it's only possible to manipulate the query with constraining eager loads.
UPDATE
Contract class
class Contract extends Model
{
public function web()
{
return $this->hasOne(Web::class);
}
}
For further readers here's an explanation how to solve this kind of problem.
Laravel returns an empty array if no records are found on a hasMany relation. If a hasOne relation is implemented, null will be returned.
So if you need an array also if no record is found on a hasOne relation, you need to do the following.
class Contract extends Model
{
public function web()
{
return $this->hasOne(Web::class)
->withDefault(function () {
return new Web();
});
}
}
As implemented like this its not possible to just return an empty array. Why this isn't possible, check out this issue on Laravel GitHub Issue Tracker.
There is existing code that depends on the result of any Eloquent relationship to either be null, a Model instance, or a Collection of Model instances. However, the current functionality of the withDefault() method opens up the potential for returning an object that is not one of those three expected values.
If you return a new \stdClass; or an empty array, an empty instance of web is returned. To get an empty array just instanciate a new Object of the relation class. In my case new Web();.