我陷入一种非常奇怪的情况,因为如果更改whereHas
的值,查询中的某些内容将无法正常工作。为了更好地解释它,首先,请看以下查询:
$table_data = Pengelola::with('pekerjaan_aktif.cu','pendidikan_tertinggi')
->whereHas('pekerjaan', function($query) use ($id,$tipe){
$query->where('tipe',$tipe)->where('id_tempat',$id)
->where(function($q){
$q->where('sekarang','1')->orWhere('selesai','>',date('Y-m-d'));
});
})->select('*',DB::raw('
(SELECT name from pengelola_pekerjaan WHERE pengelola.id = pengelola_pekerjaan.id_pengelola) as pekerjaan_name,
(SELECT tingkat from pengelola_pekerjaan WHERE pengelola.id = pengelola_pekerjaan.id_pengelola) as pekerjaan_tingkat,
(SELECT name from pengelola_pendidikan WHERE pengelola.id = pengelola_pendidikan.id_pengelola) as pendidikan_name,
(SELECT tingkat from pengelola_pendidikan WHERE pengelola.id = pengelola_pendidikan.id_pengelola) as pendidikan_tingkat
'))->get();
它的作用是...我有3个不同的表,分别是pengelola
,pengelola_pendidikan
和pendidikan_tertinggi
pengelola_pekerjaan
和pekerjaan_aktif
中的whereHas
。
为了更了解它,这是我的三个模型:
这是pekerjaan
模型
pengelola
这是pengelola_pendidikan
class Pengelola extends Model {
use FilterPaginateOrder, LogsActivity;
protected $table = 'pengelola';
protected static $logFillable = true;
public static $rules = [
'nik'=>'required',
'name'=>'required',
'email' => 'email'
];
protected $fillable = [
'nim','nik','name','tempat_lahir','tanggal_lahir','kelamin','agama','status','alamat','hp','email','gambar','darah','tinggi','berat','kontak'
];
protected $filter = [
'nim','nik','name','tempat_lahir','tanggal_lahir','kelamin','agama','status','alamat','hp','email','darah','tinggi','berat','kontak','created_at','updated_at'
];
public function getNameAttribute($value){
return !empty($value) ? $value : '-';
}
public static function initialize()
{
return [
'nim' => '','nik' => '','name' => '','tempat_lahir' => '','tanggal_lahir' => '','kelamin' => '','agama' => '','status' => '','alamat' => '','hp' => '','email' => '','darah' => '','tinggi' => '','berat' => '','kontak' => ''
];
}
public function pendidikan(){
return $this->hasMany('App\PengelolaPendidikan','id_pengelola','id');
}
public function pendidikan_tertinggi(){
return $this->hasOne('App\PengelolaPendidikan','id_pengelola','id')->orderBy('tingkat','desc')->latest();
}
public function pekerjaan(){
return $this->hasMany('App\PengelolaPekerjaan','id_pengelola','id');
}
public function pekerjaan_aktif(){
return $this->hasOne('App\PengelolaPekerjaan','id_pengelola','id')->where('sekarang','1')->orWhere('selesai','>',date('Y-m-d'))->latest();
}
public function keluarga(){
return $this->hasMany('App\PengelolaKeluarga','id_pengelola','id');
}
public function anggotacu(){
return $this->hasMany('App\PengelolaAnggotaCU','id_pengelola','id');
}
public function organisasi(){
return $this->hasMany('App\PengelolaOrganisasi','id_pengelola','id');
}
}
这是class PengelolaPendidikan extends Model {
use FilterPaginateOrder, LogsActivity;
protected $table = 'pengelola_pendidikan';
protected static $logFillable = true;
protected $fillable = [
'id_pengelola','name','tingkat','tempat','mulai','selesai','sekarang'
];
protected $filter = [
'name','tingkat','tempat','mulai','selesai','sekarang','created_at','updated_at'
];
public function getNameAttribute($value){
return !empty($value) ? $value : '-';
}
public static function initialize()
{
return [
'name' => '','tingkat' => '','tempat' => '','mulai' => '','selesai' => '','sekarang' => ''
];
}
}
pengelola_pekerjaan
,正如您在class PengelolaPekerjaan extends Model {
use FilterPaginateOrder, LogsActivity;
protected $table = 'pengelola_pekerjaan';
protected static $logFillable = true;
protected $fillable = [
'id_pengelola','id_tempat','tipe','name','tingkat','mulai','selesai','sekarang'
];
protected $filter = [
'id_tempat','tipe','name','tingkat','mulai','selesai','sekarang','created_at','updated_at'
];
public function getNameAttribute($value){
return !empty($value) ? $value : '-';
}
public static function initialize()
{
return [
'id_tempat' => 0,'tipe' => '','name' => '','tingkat' => '','mulai' => '','selesai' => '','sekarang' => ''
];
}
public function pengelola(){
return $this->belongsTo('App\Pengelola','id_pengelola','id');
}
public function lembaga(){
return $this->belongsTo('App\Lembaga','id_tempat','id')->select(array('id','name'));
}
public function cu(){
return $this->belongsTo('App\Cu','id_tempat','id')->select(array('id','no_ba','name'))->withTrashed();
}
}
中看到的那样,我正在使用2个外部变量,分别是whereHas
和$tipe
,因此,如果我的$id
却在我的{ $tipe = 1
不是$tipe
,则不会返回任何内容。
,然后如果我将1
查询更改为此查询(仅删除$table_data
上的select),则该查询将适用于任何pengelola_pendidikan
$tipe
那到底是怎么回事?对于那些想知道为什么需要这种选择的人,这是因为我需要在我的特征$table_data = Pengelola::with('pekerjaan_aktif.cu','pendidikan_tertinggi')
->whereHas('pekerjaan', function($query) use ($id,$tipe){
$query->where('tipe',$tipe)->where('id_tempat',$id)
->where(function($q){
$q->where('sekarang','1')->orWhere('selesai','>',date('Y-m-d'));
});
})->select('*',DB::raw('
(SELECT name from pengelola_pekerjaan WHERE pengelola.id = pengelola_pekerjaan.id_pengelola) as pekerjaan_name,
(SELECT tingkat from pengelola_pekerjaan WHERE pengelola.id = pengelola_pekerjaan.id_pengelola) as pekerjaan_tingkat
'))->get();
的返回json的根部出现一个列别名,该特征处理搜索,排序和分页。为此,我需要使用FilterPaginateOrder
而不是pekerjaan_name
来对此特征进行排序。
pekerjaan_aktif.name
因此,我需要一个解决方案,该解决方案具有一个根字段,该根字段由从关联表列中的select as from关系表列创建(trait FilterPaginateOrder {
protected $operators = [
'equal_to' => '=',
'not_equal' => '<>',
'less_than' => '<',
'greater_than' => '>',
'less_than_or_equal_to' => '<=',
'greater_than_or_equal_to' => '>=',
'in' => 'IN',
'not_in' => 'NOT_IN',
'like' => 'LIKE',
'between' => 'BETWEEN'
];
public function scopeFilterPaginateOrder($query)
{
$request = request();
$v = Validator::make($request->all(), [
'column' => 'required|in:'.implode(',', $this->filter),
'direction' => 'required|in:asc,desc',
'per_page' => 'required|integer|min:1',
'search_operator' => 'required|in:'.implode(',', array_keys($this->operators)),
'search_column' => 'required|in:'.implode(',', $this->filter),
'search_query_1' => 'max:255',
'search_query_2' => 'max:255'
]);
if($v->fails()) {
//for debug
// dd($v->messages());
}
return $query->orderBy($request->column, $request->direction)
->where(function($query) use ($request) {
// check if search query is empty
if($request->has('search_query_1')) {
// determine the type of search_column
// check if its related model, eg: customer.id
if($this->isRelatedColumn($request)) {
list($relation, $relatedColumn) = explode('.', $request->search_column);
return $query->whereHas($relation, function($query) use ($relatedColumn, $request) {
return $this->buildQuery(
$relatedColumn,
$request->search_operator,
$request,
$query
);
});
} else {
// regular column
return $this->buildQuery(
$request->search_column,
$request->search_operator,
$request,
$query
);
}
}
})
->paginate($request->per_page);
}
protected function isRelatedColumn($request)
{
return strpos($request->search_column, '.') !== false;
}
protected function buildQuery($column, $operator, $request, $query)
{
switch ($operator) {
case 'equal_to':
case 'not_equal':
case 'less_than':
case 'greater_than':
case 'less_than_or_equal_to':
case 'greater_than_or_equal_to':
$query->where($column, $this->operators[$operator], $request->search_query_1);
break;
case 'in':
$query->whereIn($column, explode(',', $request->search_query_1));
break;
case 'not_in':
$query->whereNotIn($column, explode(',', $request->search_query_1));
break;
case 'like':
$query->where($column, 'like', '%'.$request->search_query_1.'%');
break;
case 'between':
$query->whereBetween($column, [
$request->search_query_1,
$request->search_query_2
]);
break;
default:
throw new Exception('Invalid Search Operator', 1);
break;
}
return $query;
}
}
而不是pendidikan_name
,还有pendidikan_tertinggi.name
而不是{{1} }(在我的json返回上),使其可以与我的cu_name
特性一起使用。
答案 0 :(得分:0)
对我来说,这比Laravel Eloquent的问题更重要的是联接和SQL问题。
尝试使用
Foo
在代码的开头以及对模型的调用之后,您可以使用
DB::connection()->enableQueryLog();
因此,通过这种方式,您将能够检查生成的查询并修复导致问题的任何原因。