【问题标题】:Laravel 4 Method ImprovementLaravel 4 方法改进
【发布时间】:2013-08-08 23:14:52
【问题描述】:

我有这个索引方法:

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 专家可以帮助我进一步改进它,以便查询更快,代码更轻。

提前致谢。

【问题讨论】:

  • 圣球!修复你的缩进
  • @afarazit 缩进是怎么回事?

标签: mysql laravel laravel-4 eloquent


【解决方案1】:

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

这是新的索引方法:

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 毫秒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-22
    • 2015-09-13
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    相关资源
    最近更新 更多