-1

我有这个索引方法:

public function index()
{
    // In the view, there are several multiselect boxes (account managers, company names and account types). This code retrives the values from the POST method of the form/session.
    $company_names_value = Input::get('company_names_value');
    $account_managers_value = Input::get('account_managers_value');
    $account_types_value = Input::get('account_types_value');

    // If there has been no form submission, check if the values are empty and if they are assign a default.
    // Essentially, all of the records in the table column required.
    if (is_null($company_names_value))
    {
        $company_names_value = DB::table('accounts')
            ->orderBy('company_name')
            ->lists('company_name');
    }

    if (is_null($account_managers_value))
    {    
        $account_managers_value = DB::table('users')
            ->orderBy(DB::raw('CONCAT(first_name," ",last_name)'))
            ->select(DB::raw('CONCAT(first_name," ",last_name) as amname'))
            ->lists('amname');
    }

    if (is_null($account_types_value))
    {
        $account_types_value = DB::table('account_types')
            ->orderBy('type')
            ->lists('type');
    }

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

    // This code retrieves the order from the session that has been selected by the user by clicking on a table column title. The value is placed in the session via the getOrder() method and is used later in the Eloquent query and joins.
    $order = Session::get('account.order', 'company_name.asc');
    $order = explode('.', $order);

    // Here we perform the joins required and order the records, then select everything from accounts and select their id's as aid. Then whereIn is used to select records where company name, account manager name and account type matches the values of the multiselect boxes or the default set above.
    $accounts_query = Account::leftJoin('users', 'users.id', '=', 'accounts.user_id')
        ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
        ->orderBy($order[0], $order[1])
        ->select(array('accounts.*', DB::raw('accounts.id as aid')));

    if (!empty($company_names_value)) $accounts_query = $accounts_query->whereIn('accounts.company_name', $company_names_value);

    $accounts = $accounts_query->whereIn(DB::raw('CONCAT(users.first_name," ",users.last_name)'), $account_managers_value)
        ->whereIn('account_types.type', $account_types_value)
        ->paginate($perPage)->appends(array('company_names_value' => Input::get('company_names_value'), 'account_managers_value' => Input::get('account_managers_value'), 'account_types_value' => Input::get('account_types_value')));

    $accounts_trash = Account::onlyTrashed()
        ->leftJoin('users', 'users.id', '=', 'accounts.user_id')
        ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
        ->orderBy($order[0], $order[1])
        ->select(array('accounts.*', DB::raw('accounts.id as aid')))
        ->get();

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

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

    $this->layout->content = View::make('admin.accounts.index', array(
        'accounts'          => $accounts,
        'accounts_trash'    => $accounts_trash,
        'company_names'     => DB::table('accounts')->orderBy('company_name')->lists('company_name', 'company_name'),
        'account_managers'  => DB::table('users')->orderBy(DB::raw('CONCAT(first_name," ",last_name)'))->select(DB::raw('CONCAT(first_name," ",last_name) as amname'))->lists('amname', 'amname'),
        'account_types'     => DB::table('account_types')->orderBy('type')->lists('type', 'type'),
        'perPage'           => $perPage,
        'message'           => $message,
        'default'           => $default
    ));
}

基本上,我正在构建一个搜索多个表的查询(因此是连接)。在视图中,用户可以从各种多选框中选择多个值,然后提交一个表单,该表单将填充 $company_names_value、$account_managers_value 和 $account_types_value 变量。

最初,当没有表单提交时,我使用查询生成器选择每种类型的所有记录,然后在查询中使用它们。

它有效,但速度缓慢且混乱。我想知道你们是否有任何 Laravel 4 大师可以帮助我进一步改进它,以便查询更快并且代码更轻。

提前致谢。

4

1 回答 1

0

现在已经对它进行了重大重构,现在速度非常快。我已经将大部分代码移到我的模型中,并重构了该代码。

这是新的索引方法:

public function index()
{
    $account = explode(',', Input::get('account'));
    $account_manager = explode(',', Input::get('account_manager'));
    $account_type = explode(',', Input::get('account_type'));

    $perPage = Input::get('perPage', 10);

    $order = Session::get('account.order', 'company_name.asc');
    $order = explode('.', $order);

    $accounts = Account::accounts($order, $account, $account_manager, $account_type)->paginate($perPage)->appends(array(
        'account'           => Input::get('account'),
        'account_manager'   => Input::get('account_manager'),
        'account_type'      => Input::get('account_type'),
        'perPage'           => Input::get('perPage')
    ));

    $accounts_trash = Account::accountsTrash($order)->get();

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

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

    $this->layout->content = View::make('admin.accounts.index', compact('accounts', 'accounts_trash', 'message', 'default'));
}

以及在我的 AJAX 调用期间使用的控制器中的新 getAccountByName() 方法。这可能应该在模型中:

public function getAccountByName()
{
    $name = Input::get('account');
    return Account::select(array('id', DB::raw('company_name as text')))->where('company_name', 'like', "%$name%")->get();
}

最后是我的模型中用于检索帐户和帐户垃圾的两种新方法:

public function scopeAccounts($query, $order, $account, $account_manager, $account_type)
{
    $query->leftJoin('users', 'users.id', '=', 'accounts.user_id')
        ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
        ->orderBy($order[0], $order[1])
        ->select(array('accounts.*', DB::raw('accounts.id as aid')));

    if (!empty($account[0])) {
       $query = $query->whereIn('accounts.id', $account);
    }
    if (!empty($account_manager[0])) {
       $query = $query->whereIn('users.id', $account_manager);
    }
    if (!empty($account_type[0])) {
       $query = $query->whereIn('account_types.id', $account_type);
    }
}

public function scopeAccountsTrash($query, $order)
{
    $query->onlyTrashed()
        ->leftJoin('users', 'users.id', '=', 'accounts.user_id')
        ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
        ->orderBy($order[0], $order[1])
        ->select(array('accounts.*', DB::raw('accounts.id as aid')));
}

同样,这里可能有很多事情需要整理,但我肯定更接近于更快、更清洁的解决方案。这样做可以将加载时间从 12 秒减少到 234 毫秒。

于 2013-08-14T16:53:39.377 回答