Я определил отношение между несколькими типами магазинов и типами платежей, представляющими, какой магазин предлагает какой способ оплаты. Это определяется через morphToMany. Поэтому при вызове $ shop-> paymentMethods () будут возвращены все активные способы оплаты.
Теперь у меня также реализована функция локализации, которая работает следующим образом: Текущая локаль, в которой вы работаете, это хранится в сеансе. Затем существует таблица локализаций, в которой хранятся локализованные элементы (в данном случае - модифицированная модель магазина), поскольку разные страны снова будут предоставлять разные способы оплаты для одного и того же магазина. Эта локализация затем также сохраняет массив прикрепленных идентификаторов, когда отношение изменяется в представлении локализации, так что способы оплаты могут добавляться и удаляться во время просмотра. В этом примере они хранятся в $shop->paymentMethods_en
. Теперь легко исключить отношения, существующие в представлении root, вызвав подзапрос ->whereIn('payment_methods.id', $this->paymentMethods_en)
.
Что вызывает проблемы, так это отображение дополнительных способов оплаты, которых нет в root и, следовательно, также не существует в таблице отношений. Я попытался использовать объединение, а затем оставил внешнее соединение с таблицей отношений, что исключает все элементы, которые уже определены в наборе данных root. В противном случае идентификатор 1, например, будет загружен дважды. Затем все остальные идентификаторы методов оплаты добавляются к выводу.
Пока все хорошо. Фактически, табличное представление загружается как ожидалось (laravel nova), показывая также дополнительные способы оплаты, но когда nova пытается подсчитать существующие модели для разбивки на таблицы, я получаю ошибку: Column already exists (1060): duplicate column name 'id'
Shop.php
function paymentMethods() {
$fields = array_map(function ($el) {
return 'name as pivot_' . $el;
}, Payables::PIVOT_FIELDS);
return $this->morphToMany('App\PaymentMethod', 'payable')
->withPivot(Payables::PIVOT_FIELDS)
->using(Payables::class)
->where(function ($q) {
if (isset($this->paymentMethods_en)) {
$q->whereIn('payment_methods.id', $this->paymentMethods_en);
}
})
->unionAll(function ($q) use ($fields) {
$q->select($fields)
->from('payment_methods')->join('payables', 'payment_methods.id', '=', 'payables.id', 'left outer')
->where('payables.payable_id', '=', $this->id)
->where('payables.payable_type', '=', self::class)
->whereIn('payment_methods.id', $this->paymentMethods_en);
});
}
В соответствии с SQL UNION двух запросов, ошибка с повторяющимся именем столбца Мне пришлось бы явно указать столбцы, что невозможно при использовании красноречивые методы. Любые идеи, как обойти эту проблему - или другой подход к тому, как прикрепить отсутствующие отношения?!
Цените вашу помощь!