Laravel 4中的多选过滤搜索

时间:2013-08-08 13:15:36

标签: mysql laravel laravel-4 eloquent query-builder

我需要帮助/指导,为我的Laravel 4应用程序开发多选过滤搜索。

我的数据库中有一个名为'accounts'的表。此表通过以下关系链接到数据库中的其他表:

'用户'属于(用户模型与帐户有很多关系) 'account_types'via属于(AccountType模型与帐户有一个关系)

在我看来,我想要3个多选框,公司名称(取自帐户表'company_name'字段),帐户管理员(取自account_managers表,'first_name'和'last_name'字段)和帐户类型(取自account_types表,'type'字段)。

当用户从这些多选框中选择值并提交表单时,我需要搜索相关表并返回结果。我不想为此使用连接,因为它非常慢。特别是,当重新选择多选框的值时。

如果可能的话,我想以一种快速恢复结果的方式使用Eloquent关系。

我使用连接和查询字符串,但它非常慢,最多10到15秒。

我希望有人可以帮我解决这个问题。欢呼声。

1 个答案:

答案 0 :(得分:0)

好吧,我现在通过实现select2而不是简单地一次性加载所有联系人,就像魅力一样。工作得更好。

这是AdminContactsController.php中的索引方法:

public function index()
{

    $contact_names_value = explode(',', Input::get('contact_names_value'));
    $accounts_value = explode(',', Input::get('accounts_value'));
    $account_managers_value = explode(',', Input::get('account_managers_value'));

    // In the view, there is a dropdown box, that allows the user to select the amount of records to show per page. Retrive that value or set a default.
    $perPage = Input::get('perPage', 10);

    // This code retrieves the order from  that has been selected by the user by clicking on table ciolumn titles. The value is placed in the session and is used later in the Eloquent query and joins.
    $order = Session::get('contact.order', 'cname.asc');
    $order = explode('.', $order);

    $message = Session::get('message');

    $default = ($perPage === null ? 10 : $perPage);

    $contacts_trash = Contact::contactsTrash($order)->get();

    $this->layout->content = View::make('admin.contacts.index', array(
        'contacts'          => Contact::contacts($order, $contact_names_value, $accounts_value, $account_managers_value, $perPage)->paginate($perPage)->appends(array('accounts_value' => Input::get('accounts_value'), 'account_managers_value' => Input::get('account_managers_value'))),
        'contacts_trash'    => $contacts_trash,
        'perPage'           => $perPage,
        'message'           => $message,
        'default'           => $default
    ));
}

我的Contact.php模型中的scopeContacts方法:

public function scopeContacts($query, $order, $contact_names_value, $accounts_value, $account_managers_value, $perPage)
{
    $query->leftJoin('accounts', 'accounts.id', '=', 'contacts.account_id')
        ->leftJoin('users', 'users.id', '=', 'accounts.user_id')
        ->orderBy($order[0], $order[1])
        ->select(array('contacts.*', DB::raw('contacts.id as cid'), DB::raw('CONCAT(contacts.first_name," ",contacts.last_name) as cname'), DB::raw('CONCAT(users.first_name," ",users.last_name) as amname')));

    if (empty($contact_names_value[0])) {
        //
    } else {
        $query = $query->whereIn('contacts.id', $contact_names_value);
    }

    if (empty($accounts_value[0])) {
        //
    } else {
        $query = $query->whereIn('accounts.id', $accounts_value);
    }

    if (empty($account_managers_value[0])) {
        //
    } else {
        $query->whereIn('users.id', $account_managers_value);
    }
}

这是我的JS代码:

$('#contact_names_value').select2({
    placeholder: 'Search contacts',
    minimumInputLength: 3,
    ajax: {
        url: '/admin/get-contact',
        dataType: 'json',
        data: function (term, page) {
            return {
                contact_names_value: term
            };
        },
        results: function (data, page) {
            return {results: data};
        }
    },
    tags: true
});

这是我的方法getContactByName在我的AdminContactsController.php(为用户和帐户实现的类似方法)代码中实现的代码:

public function getContactByName()
{
    $name = Input::get('contact_names_value');
    return Contact::select(array('id', DB::raw('concat(first_name," ",last_name) as text')))->where(DB::raw('concat(first_name," ",last_name)'), 'like', "%$name%")->get();
}

请注意,在我的select语句中,我执行DB :: raw并将'first_name'和'last_name'字段设置为'text'。我认为这是主要问题之一,因为插件需要“id”和“text”才能运行。

我的路线很简单:

Route::get('admin/get-contact', 'AdminContactsController@getContactByName');