Поиск красноречивых отношений Laravel не работает должным образом - PullRequest
0 голосов
/ 08 марта 2019

Я новичок в Laravel и столкнулся с проблемой красноречивого поискового запроса. У меня две таблицы assets и assets_maintenance. Они имеют отношение к ним, которое assets hasMany assets_maintenance в модели активов assets принадлежит к assets_maintenance в модели asset_maintenance при поиске пользователя, тогда я добавляю следующий код для получения результатов.

$data['reports'] = AssetMaintenance::with(['assets'])
    ->where('inspector_id',$tenant_inspector_id)
    ->where('maintenance_due_date','>=',Carbon::now()->startOfDay())
    ->whereHas('assets',function($query){
        $query->active();//is_delete=0
    })
    ->whereHas('assets',function($query) use($stext){
        $query->where('asset_reference','like',"%{$stext}%")
                ->orWhere('asset_detail','like',"%{$stext}%");

    })
    ->orWhereHas('assets.assetCategory',function($query) use($stext){
        $query->where('assets_category.name','like',"%{$stext}%");
    })
    ->orWhere('maintenance_due_date','like',"%{$stext}%")
    ->orWhere('maintenance_cost','like',"%{$stext}%")
    ->orderBy('maintenance_due_date','ASC')
    // ->toSql();
    ->paginate(10);

Но это не дает мне правильные результаты. Иногда это дает мне отчет о другом активе или инспекторе. Я хочу результат, где inspector_id=?, manitenance_due_date больше от now и assets активно, значит не удалено .

Другие условия необязательны asset_reference, asset_detail, assets_category.name, maintenance_due_date, maintenance_cost

enter image description here

enter image description here

Ответы [ 2 ]

0 голосов
/ 08 марта 2019

Это случай неправильного понимания приоритета, в языках && / AND всегда будет вычисляться до || / OR.Это означает, что, например, более короткая версия вашего запроса inspector_id == x AND maintenance_due_date >= Now() AND maintenance_due_date like %text% ИЛИ maintenance_cost, например% text% can be true if only maintenance cost is like text`.Поскольку оператор будет оцениваться следующим образом.

inspector_id == x AND maintenance_due_date >= Now() AND maintenance_due_date like %text%` OR maintenance_cost like %text%

преобразует равные операторы в его значения

false AND false AND false OR true

, поскольку AND имеет более высокий приоритет, и они оцениваются первыми.

false OR true

и, наконец, оценивается как true или в других случаях вы можете найти элементы, которые не связаны с конкретным инспектором, если некоторые из поисков верны.

Обернув логику поиска в подпункте where, вы получитерезультаты, которые вы хотите.

$data['reports'] = AssetMaintenance::with(['assets'])
    ->where('inspector_id',$tenant_inspector_id)
    ->where('maintenance_due_date','>=',Carbon::now()->startOfDay())
    ->whereHas('assets',function($query){
        $query->active();//is_delete=0
    })

    //here is the extra where

    ->where(function($query){
        $query->whereHas('assets',function($query) use($stext){
        $query->where('asset_reference','like',"%{$stext}%")
                ->orWhere('asset_detail','like',"%{$stext}%");

        })
    ->orWhereHas('assets.assetCategory',function($query) use($stext){
        $query->where('assets_category.name','like',"%{$stext}%");
    })
    ->orWhere('maintenance_due_date','like',"%{$stext}%")
    ->orWhere('maintenance_cost','like',"%{$stext}%")
    ->orderBy('maintenance_due_date','ASC');
    })

    ->paginate(10);

Теперь это обернет результаты поиска, относящиеся к операторам, так что там будет правильный приоритет, опять короткий пример: inspector_id == x AND (maintenance_due_date like %text% OR maintenance_cost like %text%)

0 голосов
/ 08 марта 2019

Попробуйте это

$data['reports'] = AssetMaintenance::whereHas('assets',function($query) use($stext){
     $query->active()  //is_delete=0
     $query->where('asset_reference','like',"%{$stext}%")
            ->orWhere('asset_detail','like',"%{$stext}%");
})
->where('inspector_id',$tenant_inspector_id)
->where('maintenance_due_date','>=',Carbon::now()->startOfDay())
->orWhereHas('assets.assetCategory',function($query) use($stext){
    $query->where('assets_category.name','like',"%{$stext}%");
})
->orWhere('maintenance_due_date','like',"%{$stext}%")
->orWhere('maintenance_cost','like',"%{$stext}%")
->orderBy('maintenance_due_date','ASC')
// ->toSql();
->paginate(10);
...