【问题标题】:Eloquent hasMany with foreign key on joint tableEloquent hasMany 在联合表上有外键
【发布时间】:2019-02-20 08:47:43
【问题描述】:

假设:

class List extends Model
{
    public function items(){
        return $this->hasMany(Items::class, 'c.class_id', 'class_id')
            ->rightjoin('items_classes as c', 'c.items_id', '=', 'items.id');
    }
}

问题是 Eloquent 在外键字段前面加上items,最终查询是:

SELECT * FROM items
RIGHT JOIN items_classes as c ON c.items_id = items.id
// here it is
WHERE items.c.class_id = 10

即使使用DB::raw('c.class_id') 也没有解决问题。

【问题讨论】:

  • 您的查询构建代码是什么样的?你如何定义你的查询?另外,在关系方法中也做正确的加入是一种好习惯吗?
  • 我同意@Fjarlaegur。对关系方法进行正确的连接不是一个好习惯。相反,创建一个新方法,在那里重用这个方法并在那里附加一个右连接。另外,您显示的where 条件写在哪里?
  • @Fjarlaegur 我真的不知道“您的查询构建代码是什么样的?”是什么意思。查询是由这个关系函数生成的。
  • @vivek_23 你能给我一个链接,指向任何旨在提供这种解决方案的文档吗?我需要一个例子。
  • @Omid 对于定义关系的方法,不应附加任何附加内容。这将使它在每次调用items() 时都执行,即使有时不需要它。这将使其紧密耦合。而是创建一个新方法并使用正确的连接将此方法附加到它。另外,如果查询是由这个方法本身生成的,那么就会有一些boot() 方法在执行,每次执行时都会附加这个where 条件。你能告诉我们那个方法吗?

标签: laravel laravel-5 eloquent eloquent-relationship


【解决方案1】:

如果你注意到hasMany关系方法的签名:

return $this->hasMany(Model::class, 'foreign_key', 'local_key');

这意味着当 Laravel 进行查询时,它会将第二个参数 foreign_key 视为在 Model::class 中定义的 table 的列。

为了简化你的情况:

return $this->hasMany(Items::class, 'c.class_id', 'class_id')->...

暂时将 rightjoin 放在一边,Laravel 将 c.class_id 视为 Item::class 表的外键,这确实是 items 表。

所以结果查询是:

SELECT * FROM items WHERE items.c.class_id = 10

然后当你添加正确的连接时,laravel 只是添加到主查询中并使其:

SELECT * FROM items
RIGHT JOIN items_classes as c ON c.items_id = items.id
WHERE items.c.class_id = 10

Laravel 不会在关系中引用 items_classes,因为您将 List 模型关联到 Item::class 而不是 ItemClass::class

我不确定你需要的数据,但看看你是否可以像下面这样使用:

class List extends Model
{
    public function items(){
        return $this->hasMany(Items::class, 'c.class_id', 'class_id');
    }

}


List::with(['items', function($q){

    return $q->->rightjoin('items_classes as c', 'c.items_id', '=', 'items.id');
}])->get();

希望这能让您了解如何更新您的关系以获得所需的查询。如果您添加所需的表结构和数据,我可以为您更新包含关系的答案。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 2018-04-13
  • 2021-07-02
  • 1970-01-01
  • 2015-01-06
  • 1970-01-01
相关资源
最近更新 更多