ОК, вот что мы придумали.
Теперь мы используем одну модель, и имена таблиц ДОЛЖНЫ быть одинаковыми в обеих базах данных (setTable, похоже, не работает, даже если существует в исходном коде базы данных / Eloquent / Model - возможно, поэтомуне задокументировано).В любом случае = просто используйте обычную модель и убедитесь, что таблицы идентичны (или, по крайней мере, поля, которые вы используете):
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Widget extends Model
{
}
Тогда у нас есть универсальный «контроллер слияния», где модель и дополнительная сортировкапередаются в запросе (мы жестко закодировали здесь «где» и ключ, но их также можно сделать динамическими).Обратите внимание, что это не будет работать со статическими методами, которые создают новые инстансы, такие как $ model :: all (), поэтому вам нужно использовать $ model-> get () в этом случае:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class MergeController extends Controller
{
public function index(Request $request)
{
//TODO: add some validations to ensure model is provided
$model = app("App\\Models\\{$request['model']}");
$sort = $request['sort'] ? $request['sort'] : 'id';
$src_collection = $model->where('active', '1')->orderBy('name')->get();
// we setup the tenants connection elsewhere, but use it here
if(Schema::connection('tenant')->hasTable($model->getTable())) {
$model->setConnection('tenant');
$tenant_collection = $model->get()->where('active', '1');
$src_collection = $src_collection->keyBy('id')->merge($tenant_collection->keyBy('id'))->sortBy('name');
}
return $src_collection;
}
}
Если вы dd ($ src_collection);перед его возвратом вы увидите правильное соединение для каждой строки (в зависимости от данных в таблицах).Если вы обновите строку:
$test = $src_collection->find(2); // this is a row from the tenant db in our data
$test->name = 'Test';
$test->save();
$test2 = $src_collection->find(1); // this is a row from the tenant db in our data
$test2->name = 'Test2'; // this is a row from the COMMON db in our data
$test2->save();
dd($src_collection);
Вы увидите, что правильные данные обновляются независимо от того, из какой таблицы получены строки.
В результате каждый арендатор может по желаниюпереопределять и / или добавлять к данным базовой таблицы, не влияя на данные самой базовой таблицы или других арендаторов, минимизируя дублирование данных, тем самым упрощая обслуживание (очевидно, что управление данными и заполнением таблицы в другом месте, как и в любой другой таблице).Если у арендатора нет переопределений, то возвращаются данные базовой таблицы.Документация по слиянию и пользовательскому сбору имеет минимальную документацию, так что это заняло некоторое время, чтобы выяснить.Надеюсь, что это поможет кому-то еще когда-нибудь!