我正在处理以下情况:我有两个模型,一个是带有 id
和 name
字段的 Employee
和一个 Telephone
与 id
、employee_id
和 flag
字段。这两个模型之间还存在着一对多的关系,即一个员工可能有多个电话,一个电话可能属于一个员工。
class Employee extends Model
{
public function telephones()
{
return $this->hasMany(Telephone::class);
}
}
class Telephone extends Model
{
public function employee()
{
return $this->belongsTo(Employee::class);
}
}
Employee
模型引用名为 mydb1
的数据库模式中存在的表 employees
,而 Telephone
模型与存在于名为 mydb2
的不同数据库模式中的 telephones
表相关。
我想要的是使用 Eloquent 仅获取具有至少一部电话的特定标志eager loaded的员工并且(如果可能)不是查询构建器
我到目前为止没有成功的尝试是:
1) 在Controller中使用whereHas方法
$employees = Employee::whereHas('telephones', function ($query) {
$query->where('flag', 1); //Fetch only the employees with telephones of flag=1
})->with([
'telephones' => function ($query) { //Eager load only the telephones of flag=1
$query->where('flag', 1);
}
])->get();
我在这里尝试做的是,首先仅检索拥有 flag=1 的电话的员工,其次仅急切加载这些电话,但我得到以下查询异常,因为不同的使用的数据库连接:
未找到基表或 View :表 mydb1.telephones 不存在(这是真的,telephones 存在于 mydb2 中)
2) Controller 中带有约束的预加载
$employees = Employee::with([
'telephones' => function ($query) {
$query->where('flag', 1);
},
])->get();
此方法急切地加载带有 flag=1 的电话,但它返回所有 员工实例,这不是我真正想要的。我想收集 只有有电话的员工模型 flag
= 1,不包括 telephones = []
最佳答案
考虑到this post , this post和@Giedrius Kiršys 在下面的回答,我终于想出了一个适合我需要的解决方案,使用以下步骤:
- 创建一个返回模型中的关系对象的方法
- eager load Controller 中的这种新关系
- 使用模型中的查询范围过滤掉标记为 != 1 的电话
在员工模型中
/**
* This is the new relationship
*
*/
public function flaggedTelephones()
{
return $this->telephones()
->where('flag', 1); //this will return a relation object
}
/**
* This is the query scope that filters the flagged telephones
*
* This is the raw query performed:
* select * from mydb1.employees where exists (
* select * from mydb2.telephones
* where telephones.employee_id = employee.id
* and flag = 1);
*
*/
public function scopeHasFlaggedTelephones($query, $id)
{
return $query->whereExists(function ($query) use ($id) {
$query->select(DB::raw('*'))
->from('mydb2.telephones')
->where('telephones.flag', $flag)
->whereRaw('telephones.employee_id = employees.id');
});
}
在 Controller 中
现在我可以使用这种优雅的语法,就像 Eloquent 一样
$employees = Employee::with('flaggedTelephones')->hasFlaggedTelephones()->get();
读起来像“获取所有带有已标记电话的员工,然后只获取至少拥有一部已标记电话的员工”
编辑:
在与 Laravel 框架打交道一段时间后(当前版本使用 5.2.39),我想,事实上,如果关系模型存在于使用 from()
方法的不同数据库,如下所示:
$employees = Employee::whereHas('telephones', function($query){
$query->from('mydb2.telephones')->where('flag', 1);
})->get();
@Rob Contreras 声明了 from()
方法的使用,但看起来该方法需要将数据库和表作为参数。
关于mysql - 在 Laravel 5.2 中使用多个 MySQL 数据库连接查询关系是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36500518/