laravel 多对多链接 where 子句
laravel many to many with chaining where clause
我有给定的 table :
tools toolparts parts part_details
----- --------- ----- ------------
id* id* id* id*
name tool_id name part_id
part_id total (int)
----- --------- ----- ------------
工具和零件之间的关系是多对多。部件和 part_details 之间的关系是一对多的。
使用 Laravel 模型,我怎样才能获得零件最大 part_details.total 的工具??
//tool model
public function parts()
{
return $this->belongsToMany('App\Part', 'tool_part');
}
//part model
public function tools()
{
return $this->belongsToMany('App\Tool', 'tool_part')
}
public function details(){
return $this->hasMany('App\Part_detail');
}
//partDetail model
public function part(){
return $this->belongsTo('App\Part');
}
控制器
public function index()
{
$tools = Tool::with('parts', 'parts.details')->has('parts')->get();
return $tools;
}
我期望的是这样的:
控制器
public function index()
{
$tool = Tool::with('SinglePartThatHasHigestTotalInPartDetail');
}
有什么想法吗??
使用hasManyThrough关系获取与工具相关的所有零件详细信息,然后您可以逐一查看记录并获得工具零件的最高总数。
//工具型号
public function partsdetails()
{
return $this->hasManyThrough('App\PartDetail', 'App\Part','tool_id','part_id');
}
在您的控制器中
$data = Tool::all();
$array = [];
if(isset($data) && !empty($data)) {
foreach ($data as $key => $value) {
$array[$value->id] = Tool::find($value->id)->partsdetails()->max('total');
}
}
if(is_array($array) && !empty($array)) {
$maxs = array_keys($array, max($array));
print_r($maxs);// This array return the max total of the tool related parts
}
else{
echo "No Data Available";
}
您可以使用Laravel aggregates查询得到想要的结果,
在您的代码中使用 max()
函数,
public function index()
{
$tool = Tool::with(['parts.part_details' => function ($query) {
$max = $query->max('total');
$query->where('total',$max);
})->first();
}
我还没有测试过这个,但你可以这样做。
如果您遇到任何错误,请发表评论。
我用 "hacky" 方式解决我的问题。如果有人有更好更优雅的解决方案,请告诉我。
//刀具型号
public function partWithHighestTotalDelivery($trans_date = null){
if (is_null($trans_date)) {
$trans_date = date('Y-m-d');
}
$parts = $this->parts;
$highest_total_delivery = 0;
foreach ($parts as $key => $part) {
$part->detail;
$total_delivery = $part->first_value;
if (isset( $part->detail->total_delivery )) {
$total_delivery += $part->detail->total_delivery;
}
if ($highest_total_delivery < $total_delivery ) {
$highest_total_delivery = $total_delivery;
$part->total_delivery = $highest_total_delivery;
$result = $part;
}
}
if (!isset($result)) {
$result = null;
}
$this->part = $result;
}
在控制器中我有:
public function index(Request $request){
$tools = Tool::has('parts')
->get();
$tools->each(function($tool){
$tool->partWithHighestTotalDelivery();
});
return $tools;
}
有了这个,我需要运行tool->partWithHighestTotalDelivery()
tools.count次。如果工具很多,这是一个值得注意的过程。
而且,为了简单起见,我 post 的代码和我问的问题有一点 difference.that 的
您可以从零件细节开始,然后从那里获取工具:
$maxPartDetail = Part_detail::orderByDesc('total')->first();
$tools = $maxPartDetail->part->tools;
我有给定的 table :
tools toolparts parts part_details
----- --------- ----- ------------
id* id* id* id*
name tool_id name part_id
part_id total (int)
----- --------- ----- ------------
工具和零件之间的关系是多对多。部件和 part_details 之间的关系是一对多的。
使用 Laravel 模型,我怎样才能获得零件最大 part_details.total 的工具??
//tool model
public function parts()
{
return $this->belongsToMany('App\Part', 'tool_part');
}
//part model
public function tools()
{
return $this->belongsToMany('App\Tool', 'tool_part')
}
public function details(){
return $this->hasMany('App\Part_detail');
}
//partDetail model
public function part(){
return $this->belongsTo('App\Part');
}
控制器
public function index()
{
$tools = Tool::with('parts', 'parts.details')->has('parts')->get();
return $tools;
}
我期望的是这样的:
控制器
public function index()
{
$tool = Tool::with('SinglePartThatHasHigestTotalInPartDetail');
}
有什么想法吗??
使用hasManyThrough关系获取与工具相关的所有零件详细信息,然后您可以逐一查看记录并获得工具零件的最高总数。
//工具型号
public function partsdetails()
{
return $this->hasManyThrough('App\PartDetail', 'App\Part','tool_id','part_id');
}
在您的控制器中
$data = Tool::all();
$array = [];
if(isset($data) && !empty($data)) {
foreach ($data as $key => $value) {
$array[$value->id] = Tool::find($value->id)->partsdetails()->max('total');
}
}
if(is_array($array) && !empty($array)) {
$maxs = array_keys($array, max($array));
print_r($maxs);// This array return the max total of the tool related parts
}
else{
echo "No Data Available";
}
您可以使用Laravel aggregates查询得到想要的结果,
在您的代码中使用 max()
函数,
public function index()
{
$tool = Tool::with(['parts.part_details' => function ($query) {
$max = $query->max('total');
$query->where('total',$max);
})->first();
}
我还没有测试过这个,但你可以这样做。
如果您遇到任何错误,请发表评论。
我用 "hacky" 方式解决我的问题。如果有人有更好更优雅的解决方案,请告诉我。
//刀具型号
public function partWithHighestTotalDelivery($trans_date = null){
if (is_null($trans_date)) {
$trans_date = date('Y-m-d');
}
$parts = $this->parts;
$highest_total_delivery = 0;
foreach ($parts as $key => $part) {
$part->detail;
$total_delivery = $part->first_value;
if (isset( $part->detail->total_delivery )) {
$total_delivery += $part->detail->total_delivery;
}
if ($highest_total_delivery < $total_delivery ) {
$highest_total_delivery = $total_delivery;
$part->total_delivery = $highest_total_delivery;
$result = $part;
}
}
if (!isset($result)) {
$result = null;
}
$this->part = $result;
}
在控制器中我有:
public function index(Request $request){
$tools = Tool::has('parts')
->get();
$tools->each(function($tool){
$tool->partWithHighestTotalDelivery();
});
return $tools;
}
有了这个,我需要运行tool->partWithHighestTotalDelivery()
tools.count次。如果工具很多,这是一个值得注意的过程。
而且,为了简单起见,我 post 的代码和我问的问题有一点 difference.that 的
您可以从零件细节开始,然后从那里获取工具:
$maxPartDetail = Part_detail::orderByDesc('total')->first();
$tools = $maxPartDetail->part->tools;