[英]laravel select raw not working on some models
我陷入一种非常奇怪的情况,因为如果更改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
模型
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');
}
}
这是pengelola_pendidikan
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();
}
}
并且正如您在whereHas
所看到的whereHas
我正在使用2个外部变量$tipe
和$id
,因此,如果我的$tipe = 1
但当我的$tipe
不是1
时,此查询将正常工作,它将不会返回任何内容。
然后,如果我将$table_data
查询更改为此(只删除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();
那么到底发生了什么呢? 对于那些想知道为什么需要这种选择的人,这是因为我需要在我的特征FilterPaginateOrder
的返回的json的根部出现一个列别名,该特征处理搜索,排序和分页。 为此,我需要使用pekerjaan_name
而不是pekerjaan_aktif.name
进行排序,以便对此特征进行排序。
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;
}
}
因此,我需要的是一种解决方案,该解决方案具有一个根字段,该根字段通过从关联表列中的select as创建( pendidikan_name
代替pendidikan_tertinggi.name
并且在json返回时还用cu_name
代替pekerjaan_aktif.cu.name
),以使其与我的FilterPaginateOrder
特征。
对我来说,这比Laravel Eloquent的问题更重要的是联接和SQL问题。
尝试使用DB::connection()->enableQueryLog();
进行调试 在代码的开头以及对模型的调用之后,可以使用DB::getQueryLog()
这样,您就可以检查生成的查询并修复导致问题的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.