Solution:
It is possible, if you add:
protected $with = ['company'];
to both the Service and Product models. That way, the company relation is eager-loaded every time a Service or a Product is loaded, including when loaded via the polymorphic relation with History.
Explanation:
This will result in an additional 2 queries, one for Service and one for Product, i.e. one query for each historable_type. So your total number of queries—regardless of the number of results n—goes from m+1 (without eager-loading the distant company relation) to (m*2)+1, where m is the number of models linked by your polymorphic relation.
Optional:
The downside of this approach is that you will always eager-load the company relation on the Service and Product models. This may or may not be an issue, depending on the nature of your data. If this is a problem, you could use this trick to automatically eager-load company only when calling the polymorphic relation.
Add this to your History model:
public function getHistorableTypeAttribute($value)
{
if (is_null($value)) return ($value);
return ($value.'WithCompany');
}
Now, when you load the historable polymorphic relation, Eloquent will look for the classes ServiceWithCompany and ProductWithCompany, rather than Service or Product. Then, create those classes, and set with inside them:
ProductWithCompany.php
class ProductWithCompany extends Product {
protected $table="products";
protected $with = ['company'];
}
ServiceWithCompany.php
class ServiceWithCompany extends Service {
protected $table="services";
protected $with = ['company'];
}
…and finally, you can remove protected $with = ['company']; from the base Service and Product classes.
A bit hacky, but it should work.