【问题标题】:Laravel Eloquent: multiple foreign keys for relationshipLaravel Eloquent:关系的多个外键
【发布时间】:2018-05-17 01:47:01
【问题描述】:

我正在将一个项目移植到 Laravel。

我有两个彼此处于一对多关系的数据库表。它们由三个条件连接。如何在 Eloquent 中建模这种关系?

我不应该修改数据库架构,因为它必须保持与其他事物的向后兼容。

我尝试了以下方法,但它不起作用。

拥有方:

use Illuminate\Database\Eloquent\Model;

class Route extends Model
{
    public function trips()
    {
        return $this->hasMany('Trip', 'route_name,source_file', 'route_name,source_file')
    }
}

反面:

use Illuminate\Database\Eloquent\Model;

class Trip extends Model
{
    public function routes()
    {
        return $this->belongsTo('Route', 'route_name,source_file', 'route_name,source_file');
    }
}

示例Route 数据库值:

id    | route_name     | source_file
---------------------------------------
1     | Berlin - Paris | file1.xls   
2     | Madrid - London| file2.xls
3     | Berlin - Paris | file3.xls

示例Trip 数据库值:

id        | route_name           | source_file | duration
---------------------------------------------------------
1         | Berlin - Paris       | file1.xls   | 78
2         | Madrid - London      | file2.xls   | 241
3         | Berlin - Paris       | file3.xls   | 65
1         | Berlin - Paris       | file1.xls   | 95
1         | Berlin - Paris       | file1.xls   | 65

RouteTrip 有其他属性,为了简洁,我没有在这里列出。

这在 Eloquent 中可行吗?

【问题讨论】:

  • 恐怕你用 eloquent 做不到。它不支持多个外键关系。
  • 我认为您只能拥有一个外键和本地键,但您可以在查询中添加额外的 where 子句。这对你来说足够了吗?您能否为该问题提供更多背景信息?这将有助于我们更好地理解问题。
  • @Jonathon 我将模型名称 AB 替换为我使用的实际名称,希望现在更容易理解问题域。
  • @Jonathon 您能否提供一个示例来说明您的意思并将其添加为答案?我很乐意接受它。

标签: laravel eloquent laravel-eloquent


【解决方案1】:

我不得不处理类似的问题。 @fab 提供的解决方案不适用于即时加载,因为在处理关系时 $this->source_file 将是 null。我想出了this solution

安装Compoships 并在模型中配置后,您可以定义匹配多个列的关系。

拥有方:

use Illuminate\Database\Eloquent\Model;
use Awobaz\Compoships\Compoships;

class Route extends Model
{
    use Compoships;

    public function trips()
    {
        return $this->hasMany('Trip', ['id', 'route_name', 'source_file'], ['route_id', 'route_name', 'source_file']);
    }
}

反面:

use Illuminate\Database\Eloquent\Model;
use Awobaz\Compoships\Compoships;

class Trip extends Model
{
    use Compoships;

    public function route()
    {
        return $this->belongsTo('Route', ['route_id', 'route_name', 'source_file'], ['id', 'route_name', 'source_file']);
    }
}

Compoships 支持预加载。

【讨论】:

  • 有人尝试将 Compoships 与 Fico7489 EloquentJoin (/laravel-eloquent-join) 一起使用?遗憾的是,这两个特征都有冲突
【解决方案2】:

正如Jonathon 已经提到的,您可以尝试在您的关系中添加where-clause:

use Illuminate\Database\Eloquent\Model;

class Route extends Model
{
    public function trips()
    {
        return $this->hasMany('Trip', 'route_name')->where('source_file', $this->source_file);
    }
}

反面:

use Illuminate\Database\Eloquent\Model;

class Trip extends Model
{
    public function routes()
    {
        return $this->belongsTo('Route', 'route_name')->where('source_file', $this->source_file);
    }
}

【讨论】:

  • 这不适用于即时加载,因为在处理关系时 $this->source_file 将为空。
  • 是的,这在预加载中不起作用,如果有人不需要预加载可以轻松使用它。在加载基本查询后调用这个关系。
【解决方案3】:

我将如何解决这个问题就是做这样的事情

class A
{
    public function b1()
    {
        return $this->hasMany('B', 'prop1', 'prop1')
    }
    public function b2()
    {
        return $this->hasMany('B', 'prop2', 'prop2')
    }
    public function b3()
    {
        return $this->hasMany('B', 'prop3', 'prop3')
    }

   public function getBsAttribute()
    {
        $data = collect([$this->b1, $this->b2, $this->b3]);
        return $data->unique();
    }

}

收集所有单一关系并将它们作为唯一集合返回,显然对逆也做同样的事情,这应该会给你一些数据来处理。

OP 已被修改,因此不再相关,如果有人需要类似的答案,请留下

【讨论】:

  • 我得到了 Method Illuminate\\Support\\Collection::addEagerConstraints 不存在
猜你喜欢
  • 2021-04-09
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 2020-03-28
  • 1970-01-01
  • 2021-07-05
相关资源
最近更新 更多