繁体   English   中英

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

[英]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个不同的表一个是pengelolapengelola_pendidikan我叫同为pendidikan_tertinggipengelola_pekerjaan我叫同为pekerjaan_aktifwhereHaspekerjaan

为了更了解它,这是我的三个模型:

这是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM