laravel select raw在某些模型上不起作用

时间:2018-06-22 16:10:47

标签: php sql laravel

我陷入一种非常奇怪的情况,因为如果更改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个不同的表,分别是pengelolapengelola_pendidikanpendidikan_tertinggi pengelola_pekerjaanpekerjaan_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特性一起使用。

1 个答案:

答案 0 :(得分:0)

对我来说,这比Laravel Eloquent的问题更重要的是联接和SQL问题。

尝试使用 Foo  在代码的开头以及对模型的调用之后,您可以使用 DB::connection()->enableQueryLog(); 因此,通过这种方式,您将能够检查生成的查询并修复导致问题的任何原因。