2013-08-07 5 views
-1

У меня есть этот индексный метод:Laravel Метод 4 Улучшение

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.

Первоначально, когда нет представления формы, я использую Query Builder, чтобы выбрать все записи для каждого типа, а затем использовать их в запросе.

Это работает, но оно медленное и грязное. Мне было интересно, может ли кто-нибудь из вас Гуру Laravel 4 помочь мне улучшить его дальше, чтобы запросы были быстрее, а код стал легче.

Заранее спасибо.

+1

Святые шары! исправить ваш отступ – afarazit

+0

@afarazit Что случилось с отступом? –

ответ

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')); 
} 

И Новый метод getAccountByName() в мой контроллер, который используется во время моего вызова AJAX. Это, вероятно, следует идти в модели:

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 мс.

Смежные вопросы