执行高级搜索 - 通过子关系搜索

时间:2015-08-14 17:37:27

标签: laravel laravel-5 eloquent

您好我正在尝试在我的控制器中构建搜索。这些是我的模型:

Invoice.php

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Invoice extends Model
{
    use SoftDeletes;

    protected $dates = ['deleted_at'];

    protected $table = 'invoices';

    public function customerDetails() {
        return $this->belongsTo('App\Models\CustomerDetails', 'customer_id');
    }

    public function tickets() {
        return $this->hasMany('App\Models\Ticket', 'invoice_id');
    }


}

CustomerDetails.php

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class CustomerDetails extends Model {

    protected $table = 'customer_details';

    public function user()
    {
        return $this->belongsTo('App\Models\User');
    }

    public function invoices() {
        return $this->hasMany('App\Models\Invoices', 'customer_id');
    }
}

Ticket.php

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Ticket extends Model {

    protected $table = 'tickets';

}

我有一个搜索字段,允许用户输入单个值: enter image description here

允许的搜索参数为:发票ID 客户ID 名字最后姓名电子邮件电话参考ID 购买日期

现在应该做的是转到发票表并检查输入的值是否与 invoice_id 相匹配,或者输入的值是否与 customer_id 相匹配或匹配 customer_details-&gt; first_name customer_details-&gt; last_name customer_details-&gt;电子邮件 customer_details-&gt;手机 reference_id created_at

这是我在我的控制器中尝试做的事情:

/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
    $filter = Input::get('filter');
    $invoices = "";

    if (strlen($filter) > 0)
    {
        $invoices = Invoice::where('id', '=', $filter)
            ->orWhere(function ($query) use ($filter) {
                $query->whereHas('customerDetails', function ($q) use ($filter)  {
                    $q->where('id', '=', $filter)
                    ->orWhere('first_name', '=', $filter)
                    ->orWhere('last_name', '=', $filter);
                });
            })
            ->get();
    }
    else
    {
        $invoices = Invoice::with('customerDetails')
            ->whereRaw('created_at >= CURRENT_DATE')
            ->whereRaw('created_at < CURRENT_DATE + INTERVAL 1 DAY')
            ->get();
    }

    return [
        'invoices' => $invoices
    ];
}

在我上面的代码中,我还没有添加票证关系,但我只是首先针对customer_details进行测试。

这是laravel生成的查询:

select * from `invoices` where `invoices`.`deleted_at` is null and `id` = 'Phil' or ((select count(*) from `customer_details` where `invoices`.`customer_id` = `customer_details`.`id` and `id` = 'Phil' or `first_name` = 'Phil' or `last_name` = 'Phil') >= 1)

根据返回的数据,我已经知道该查询是错误的,因为即使我输入的名称不存在,它仍会返回一些行。

我想知道我做错了什么以及如何解决它,如果这种方式快速有效。

1 个答案:

答案 0 :(得分:0)

我想通过它并最终想出了这个,我试图弄清楚如何在没有连接的情况下做到这一点但看起来不能这样做所以不得不这样做:

$invoices = Invoice::select('invoices.*')
    ->leftJoin('customer_details', 'customer_details.id', '=', 'invoices.customer_id')
    ->where('invoices.id', '=', $filter)
    ->orWhere('invoices.reference_code', '=', $filter)
    ->orWhereRaw("DATE_FORMAT(invoices.created_at, '%Y-%m-%d') = ?", array($filter))
    ->orWhere('customer_details.id', '=', $filter)
    ->orWhere('customer_details.first_name', '=', $filter)
    ->orWhere('customer_details.last_name', '=', $filter)
    ->orWhere('customer_details.email', '=', $filter)
    ->orWhere('customer_details.phone', '=', $filter)
    ->with('customerDetails')
    ->get();