首页 > 解决方案 > Eloquent Union - SQL 错误“列 'id' 已存在”

问题描述

我已经定义了几个 Shop-Types 和 PaymentMethods 之间的关系,表示哪个商店提供哪种付款方式。这是通过 morphToMany 定义的。因此,当调用 $shop->paymentMethods() 时,它将返回所有有效的付款方式。

现在我还实现了一个本地化功能,它的工作方式如下:您正在使用的当前语言环境存储在会话中。然后,有一个本地化表,它存储本地化元素(在本例中:修改后的商店模型),因为不同的国家将再次为同一商店提供不同的付款方式。然后,当在本地化视图中修改关系时,此本地化还会存储一组附加的 ID,以便可以在子视图中添加和删除支付方式。在此示例中,它们存储在$shop->paymentMethods_en

现在很容易通过调用 sub-query 来排除根视图中存在的关系->whereIn('payment_methods.id', $this->paymentMethods_en)

导致问题的原因是显示根目录中不存在的其他付款方式,因此关系表中也不存在。我尝试使用联合,然后左外连接关系表,它排除了根数据集中已经定义的所有元素。否则,例如 ID 1 将被加载两次。然后,所有剩余的付款方式 ID 都将附加到输出中。

到目前为止,太好了。实际上,表格视图按预期加载(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,重复列名错误我将不得不显式命名列,这是使用 eloquent 方法无法实现的。任何想法如何解决该问题 - 或有关如何附加缺失关系的不同方法?

标签: sqllaraveleloquentlaravel-nova

解决方案


推荐阅读