我有3个表:Laravel 5项目中的输出,产品和服务。
我想基于这种情况在一个QUERY中加入这3个表:
如果outputs.article_type = 'p'
(p = product)获取products.name
如果outputs.article_type = 's'
(s = service)获取service.name
$outputs = Output::join('products', 'products.id', '=', 'outputs.article_id')
... only if outputs.article_type is p (p=product)
->join('services', 'services.id', '=', 'outputs.article_id')
... only if outputs.article_type is s (s=service)
->select(array('outputs.output_at','---services or product---.name as article_name'))
答案 0 :(得分:0)
不确定为什么需要将逻辑放在一个查询中。似乎是应用 KISS 的完美示例。
为什么不选择带有1个参数和普通旧IF
的函数来提高可读性并使您(可能还有其他开发人员)的生活更轻松?我没有看到你正在尝试做什么的任何优势。我认为,除了简洁之外,在这种情况下,这不是最重要的因素。
在Output.php模型中:
/**
* Retrieves output of the given type.
*
* @param string $type Type of the output
*
* @return mixed Object or false in case of problems
*/
public static function getOutput($type) {
if (!isset($type) || empty($type) || !in_array($type, ['p', 's'])) {
// Wrong type
return false;
}
if ($type === 'p') {
$baseQuery = Output::join('products', 'products.id', '=', 'outputs.article_id');
$table = 'products';
} else {
$baseQuery = Output::join('services', 'services.id', '=', 'outputs.article_id');
$table = 'services';
}
return $baseQuery
->select('outputs.output_at', $table.'.name as article_name')
->get();
}
然后,在控制器中
$output = Output::getOutput('p');
if ($output && count($output)) {
// Do other stuff or pass the data to a view...
}
请记住,这没有经过测试,可能需要与我展示的略有不同的实施,但这个想法仍然很明确。
答案 1 :(得分:0)
查看A join with additional condition using Query Builder or ELoquent
但也许你应该考虑加急而不是加入?
Output::with('Product', 'Service')->....
当然你需要先添加关系
public function service() {
if ($this->article_type == 's')
return $this->belongsTo('Service', 'article_id', 'id')
else
return null;
}
并覆盖name属性以获取所需的特定名称
public functon getNameAttribute() {
if ($this->service)
return $this->service->name;
else if ($this->product)
return $this->product->name;
}