Let's say we use the same table schema for saving purchased products of orders for website A and B. Databases for A and B locate in different servers. So 2 database connections are defined.
CREATE TABLE `order_products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` int(11) NOT NULL DEFAULT '0',
`product_id` int(11) NOT NULL DEFAULT '0',
# other columns...
);
And we are building an application for analysing all orders in different platforms. We have imported and saved the data in another summary table, schema being like this
CREATE TABLE `summary_orders` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`order_id` int(10) unsigned NOT NULL,
`source` varchar(15) NOT NULL DEFAULT 'site_a', # 'site_a', 'site_b'
# other columns...
);
To access purchased products in different platforms, we define 2 identical classes but in different namespaces:
<?php
namespace Path\To\Class\SiteA;
class OrderProduct extends SiteABaseModel
{
}
<?php
namespace Path\To\Class\SiteB;
class OrderProduct extends SiteBBaseModel
{
}
To fetch purchased products of orders, in SummaryOrder class, we define a relation products:
class SummaryOrder extends Model
{
protected $sourcesToConnections = [
'source_a' => 'connection_a',
'source_b' => 'connection_b'
];
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function products()
{
$namespace = sprintf("Path\To\Class\%s", ucfirst($this->source));
$class = "$namespace\OrderProduct";
// $this->source has no value here when calling with()
$connection = $this->sourcesToConnections[$this->source];
return $this->setConnection($connection)->hasMany($class, 'id', 'order_id');
}
//...
}
Then we want to fetch all data from summary_orders like so
$orders = SummaryOrder::query()
->with(['products:product_id,order_id'])
->get()
->map(function ($order) {
// prepare more stuff
});
The above call is gonna fail because when Laravel is building a query and calling products() in SummaryOrder, there is in fact no SummaryOrder instance hence $this->source has no value. So we end up with undefined index error when accessing $sourcesToConnections: $this->sourcesToConnections[$this->source].
A "solution" is dont-do eager loading at the cost of performance:
$orders = SummaryOrder::query()
->with(['products:product_id,order_id'])
->get()
->map(function ($order) {
// prepare more stuff
$order->products;
});
Apparently this is not ideal. So my question is, how can I keep SummaryOrder::products() as flexible as possible, but also keep performance gain with() gives me?
