简体   繁体   English

Laravel雄辩的ORM多对多搜索查询

[英]Laravel Eloquent ORM many-to-many Search Query

I am using Laravel v3, with Eloquent, and a MySQL database for this application 我正在使用Laravel v3,Eloquent和该应用程序的MySQL数据库

I have an employee database, with a search form that displays a list of the employees that match the search criteria. 我有一个员工数据库,其中有一个搜索表单,其中显示了符合搜索条件的员工列表。 You can fill out one or many fields, and it will match on all the filled out fields only. 您可以填写一个或多个字段,它将仅与所有填写的字段匹配。 As seen below: http://i.stack.imgur.com/Ttfhr.png 如下所示: http : //i.stack.imgur.com/Ttfhr.png

The search all functions correctly, except for I just added the multiselect for the "Training". 搜索所有功能正常,除了我刚刚为“培训”添加了多选。 An employee can have zero to many training certificates attached to them. 员工可以附加零到许多培训证书。 If the user was to search for first name "Matt", and check off "CSTS" under the training search criteria, the list would show all employees that have a first name similar to Matt, and also have CSTS training. 如果用户要搜索名字“ Matt”,并在培训搜索条件下选中“ CSTS”,则该列表将显示所有具有与Matt相似的名字的员工,并且也接受过CSTS培训。

Database schema is as follows: 数据库架构如下:

user
--id
--first_name
--last_name
--job_title_id
etc...


training
--id
--name
--issused_date
--expiry_date

user_training
--id
--user_id
--training_id

The Model's for User and Training are as follows: 用户模型和培训模型如下:

class User extends Eloquent {

  public static $table = 'user';

  public function training(){
    return $this->has_many_and_belongs_to('training','user_training');
  }


class Training extends Eloquent {

    public static $table = 'training';


  public function users(){
      return $this->has_many_and_belongs_to('user','user_training');
  }



}

I have the following code, for the function search, and what I tried for the training: 我有以下代码用于函数搜索,以及我尝试进行的培训:

Route::post('(:bundle)/list', function() {

$search = new StdClass(); 
$search->first_name = Input::get('first_name');
$search->last_name = Input::get('last_name');
$search->job_titles = Input::get('job_titles'); // array of ids/returns null if none selected
$search->training = Input::get('training'); // array of ids/returns null if none selected
$search->city = Input::get('city');
$search->province = Input::get('province');
$search->phone = Input::get('phone');
$search->status = Input::get('status');
$search->gender = Input::get('gender');
$search->hire_from_date = Input::get('hire_from_date');
$search->hire_to_date = Input::get('hire_to_date');
$search->current_location = Input::get('current_location');
$search->role = Input::get('role');

Session::put('search', $search); // so we can access inside query builder sub-functions


$query = User::where('active', '=', true);

if(!empty($search->training)) { // one or many


    $query = User::with(array('training' => function($query) {
        $s_search = Session::get('search');
        //$query->where_in('training.id', $s_search->training);
        //foreach($s_search->training as $id) {
        //  $query->where('training.id', '=', $id);
        //}
    }));
}


//$query = User::join('user_training', 'user.id', '=', 'user_training.user_id');
//$query->join('user_training', 'user.id', '=', 'user_training.user_id');
//$query->join('training', 'training.id', '=', 'user_training.training_id');

if(!empty($search->first_name)) { $query->where('first_name', 'LIKE', '%' . $search->first_name . '%'); }
if(!empty($search->last_name)) { $query->where('last_name', 'LIKE', '%' . $search->last_name . '%'); }

if(!empty($search->city)) { $query->where('city', 'LIKE', '%' . $search->city . '%'); }
if(!empty($search->province)) { $query->where('province_id', '=', $search->province); }

if(!empty($search->gender)) { $query->where('gender', '=', $search->gender); }
if(!empty($search->phone)) { $query->where('phone_1', 'LIKE', '%' . $search->phone . '%'); }

if(!empty($search->status)) { $query->where('status_id', '=', $search->status); }
if(!empty($search->role)) { $query->where('role_id', '=', $search->role); }
if(!empty($search->current_location)) { $query->where('location_id', '=', $search->current_location); }

if(!empty($search->hire_from_date)) // "after"
    $query->where('hire_date', '>=', date('Y-m-d', strtotime($search->hire_from_date)));

if(!empty($search->hire_to_date))  // "before"
    $query->where('hire_date', '<=', date('Y-m-d', strtotime($search->hire_to_date)));

if(!empty($search->job_titles)) { // one or many
    $query->where(function($query){
        $s_search = Session::get('search');
        foreach($s_search->job_titles as $id) {
            $query->or_where('job_title_id', '=', $id);
        }
    });
}



$query->order_by('last_name');

$user_list = $query->distinct()->get();
$user_count = $query->count();

var_dump($user_list); die;


if(Input::get('action') == 'export') {

    if(Permission::check("Export Users CSV")) {
        $now = new DateTime();
        return Response::download(User::get_group_csv($user_list), date_format(new DateTime(), 'Y-m-d') . '_User_Export.csv');
    }

} 

The "$user->training" comes in as a simple array of id's, which matches up with the Training->id table “ $ user-> training”以简单的id数组形式出现,它与Training-> id表匹配

The Job Title search functions correctly with the multiselect, but the job_title_id is in the User table, not a relationship. 多重选择可以正确执行“职务标题”搜索,但是job_title_id在User表中,而不是关系中。

I have tried looping, manually joining, using eager load, using Eloquent's "with", all with no success. 我试过循环,手动加入,使用急切的加载,使用Eloquent的“ with”,但都没有成功。 Can someone point me in the right direction? 有人可以指出我正确的方向吗?

First, you don't need to use the session to get variables into your anonymous functions. 首先,您无需使用会话即可将变量获取到匿名函数中。 Try using "uses" instead. 尝试改用“用途”。

// $search already defined

$query = User::where('active', '=', true);

if(!empty($search->training)) { // one or many
    $query = User::with(array('training' => function($query) uses ($search) {
        // Now you can use $search in this context
    }));
}

} }

Also, you are using lower case strings for your relationships but the models/classes are actually capitalized so they should be like this: 另外,您在关系中使用小写字符串,但是模型/类实际上是大写的,因此它们应该像这样:

class User extends Eloquent {

    public static $table = 'user';

    public function training(){
        return $this->has_many_and_belongs_to('Training', 'user_training');
    }
}

class Training extends Eloquent {

    public static $table = 'training';

    public function users(){
        return $this->has_many_and_belongs_to('User', 'user_training');
    }
}

Third, you are declaring "$query = User::where('active', '=', true);" 第三,您声明“ $ query = User :: where('active','=',true);” and then overwriting it. 然后覆盖它。 Maybe you are looking for this: 也许您正在寻找:

if (!empty($search->training)) { // one or many
    $query = User::with(array('training' => function($query) uses ($search) {
        // Now you can use $search in this context
        $query->where_in('training.id', $search->training);
    }));
} else {
    $query = User::with(array());
}
$query = $query->where('active', '=', true);

I could give more insight but I'm not 100% on what your end goal is. 我可以提供更多的见解,但您的最终目标不是100%。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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