Laravel Eloquent: 关系的多个外键

Laravel Eloquent: multiple foreign keys for relationship

我正在将项目移植到 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 中可能吗?

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

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 已修改,因此不再相关,如果有人需要类似的答案,请留在其中

正如 已经提到的,您可以尝试在您的关系中添加一个 where 子句:

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);
    }
}

我不得不处理类似的问题。 @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 支持预先加载。