Laravel HasMany跨多个联系

时间:2017-04-27 13:25:49

标签: php laravel laravel-5 eloquent

我想在第二个表Offer上检索与Offer相关的offer_related,因为我无法更改Offer表的架构。

我在不同的连接上有两个数据库,一个是offers,另一个是offer_related

为了论证,为了清楚起见,我将按照以下方式命名数据库,以便明确哪些可以改变,哪些可以改变。

  • 包含offers以后称为immutable
  • 的数据库
  • 包含offer_related以后称为mutable
  • 的数据库

示例模式如下

connection1.mutable.offer_related

offer_id | related_offer_id
---------------------------
1        | 2
1        | 3

connection2.immutable.offers

id | name
---------------------------
1  | foo
2  | bar
3  | baz

我认为它属于belongsToMany关系,但我似乎无法做到正确。

return $this->belongsToMany(Offer::class, 'immutable.offer', 'id');

// Syntax error or access violation: 1066 Not unique table/alias: 'offer'

我还尝试使用自定义查询手动构建belongsToMany关系,但没有成功。

我希望能够致电

Offer::find(1)->related; // Offer(2), Offer(3)

非常感谢任何见解。

3 个答案:

答案 0 :(得分:1)

将关系更改为:

    return $this->belongsToMany(Offer::class, 'mutable.offer_related', 
                                'offer_id', 'related_offer_id');

您的原始查询尝试在不使用关系表(offer_related)的情况下建立关系。这就是问题所在。

答案 1 :(得分:0)

另一种解决方案是创建特征:

trait HasCrossDbRelationships {

  /**
   * Define a one-to-many relationship with connection attribute
   *
   * @param  string  $connection
   * @param  string  $related
   * @param  string  $foreignKey
   * @param  string  $localKey
   * @return \Illuminate\Database\Eloquent\Relations\HasMany
   */
  public function hasManyCrossDb($connection, $related, $foreignKey = null, $localKey = null)
  {
      $instance = $this->newRelatedInstance($related);
      $instance->setConnection($connection);

      $foreignKey = $foreignKey ?: $this->getForeignKey();

      $localKey = $localKey ?: $this->getKeyName();

      return $this->newHasMany(
          $instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey
      );
  }

}

答案 2 :(得分:-1)

我也有这个问题,然后用特征解决了:

<?php 

namespace App\Traits\Model;

use Illuminate\Support\Str;

trait HasCrossDatabaseRelation {

    public function getTable() {
        if (! isset($this->table)) {
            $this->table = str_replace(
                '\\', '', Str::snake(Str::plural(class_basename($this)))
            );
        }

        $configConnections = config('database.connections');

        $databaseName = $configConnections[$this->getConnectionName()]['database'];

        return $databaseName . "." . $this->table;
    }

}

然后使用该特征并在每个模型上设置$ connection属性。希望有帮助