如何在Laravel 4中使用很多(数千个)雄辩的记录

时间:2016-03-15 18:41:13

标签: php laravel laravel-4 datatables eloquent

我需要从客户表中获取所有数据记录,有超过18000条记录。

我使用DataTables jQuery插件来显示数据,所以我不想在这里使用paginate Laravel方法。

我只想检索数据并传递给DataTable jQuery。这个插件做了分页。

这是我的控制器代码:

$data = Client::orderBy('created_at', 'desc')->get();

我得到500错误,因为结果太大了。

我不想设置更高的内存限制,我想使用限制或类似。

我试过了:

$data = Client::orderBy('created_at', 'desc')->take(10)->skip(1200)->get();

但它只获得10条记录,而不是更多。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

你可以使用更有效且易于使用的Laravel Datatable package,这是我如何做的例子。

  

注意:我正在使用Yajra Datatable软件包,您的所有基本要求都将涵盖在此。

我的Controller方法,其中有数据表Ajax请求

public function getData()
{
    $users = User::whereHas('roles',function($q){
        $q->whereNotIn('roles.name',['user','memberstudent','educationmanager']);
    })->select(array('users.id','users.firstname','users.lastname' ,'users.username','users.email',DB::raw("'roles'"), 'users.confirmed', 'users.created_at'));        

    return Datatables::of($users)
    //->edit_column('created_at', '{{ $created_at->format("Y-m-d h:i:s") }}')
    ->edit_column('created_at', '{{ date("Y-m-d", strtotime($created_at))}}')
    ->edit_column('confirmed','@if($confirmed)
        Yes
        @else
        No
        @endif')
    ->add_column('roles','{{ implode(", ", User::find($id)->roles()->lists(\'name\')) }}')
    ->add_column('actions', '
        @if(Auth::user()->hasRole("owner"))
            <div class="btn-group">
                <a href="{{{ URL::to(\'admin/users/\' . $id . \'/edit\' ) }}}" class="iframe btn btn-xs btn-primary"><i class="fa fa-pencil"></i> {{{ Lang::get(\'button.edit\') }}}</a>
                <a href="{{{ URL::to(\'admin/users/\' . $id . \'/delete\' ) }}}" class="iframe btn btn-xs btn-danger"><i class="fa fa-trash-o"></i> {{{ Lang::get(\'button.delete\') }}}</a>
            </div>

        @elseif(Auth::user()->hasRole("superadmin") && User::find($id)->roles()->pluck(\'name\') != "owner")
            <div class="btn-group">
                <a href="{{{ URL::to(\'admin/users/\' . $id . \'/edit\' ) }}}" class="iframe btn btn-xs btn-primary"><i class="fa fa-pencil"></i> {{{ Lang::get(\'button.edit\') }}}</a>
                <a href="{{{ URL::to(\'admin/users/\' . $id . \'/delete\' ) }}}" class="iframe btn btn-xs btn-danger"><i class="fa fa-trash-o"></i> {{{ Lang::get(\'button.delete\') }}}</a>
            </div>
        @endif

        ')
    ->remove_column('id')
    ->remove_column('rn') // rownum for oracle
    ->remove_column('created_at') // rownum for oracle
    ->make();
}

我的观点是

<table id="users" class="table table-striped table-hover table-bordered">
    <thead>
        <tr>
            <th class="col-md-2">first name</th>
            <th class="col-md-2">last name</th>
            <th class="col-md-2">username</th>
            <th class="col-md-2">email</th>
            <th class="col-md-2">roles</th>
            <th class="col-md-2">activated</th>
            <th class="col-md-2">actions</th>
        </tr>
    </thead>
</table>

MY JS代码

<script type="text/javascript">
var oTable;
$(document).ready(function() {
    oTable = $('#users').dataTable( {
        "sDom": "<'row'<'col-md-6'l><'col-md-6'f>r><'row'<'col-md-6'i><'col-md-6'p>>t<'row'<'col-md-6'i><'col-md-6'p>>",
        "aoColumnDefs": [
        { "bSearchable": true, "bSortable": false, "aTargets": [ 2,5 ] }
        ],
        "sPaginationType": "bootstrap",
        "oLanguage": {
            "sLengthMenu": "_MENU_ records per page"
        },
        "bProcessing": true,
        "bServerSide": true, //this means data will come from server, ajax based
        "sAjaxSource": "{{ URL::to('admin/users/data') }}", // get data from this URL
        "fnDrawCallback": function ( oSettings ) {
            $(".iframe").colorbox({iframe:true, width:"80%", height:"80%"});
        }
    });
});
</script>

答案 1 :(得分:0)

在这种情况下,你真的需要使用服务器端分页。

依赖客户端分页(即插件的分页功能)的问题在于,包含所有18,000条记录的API的响应将 humongous ,您的用户不仅需要等待请求完成(这对于这么多数据来说可能需要几分钟),但是根据插件的工作原理,他们可能还需要等待它为所有这些记录呈现DOM。

看起来Datatables支持server-side pagination。为什么不尝试一下呢?

答案 2 :(得分:0)

我采用了另一种解决方案,使用laravel中的paginate方法并忘记了DataTables插件,DataTables是一个很棒的插件!但在我的情况下,要使用这个插件,必须实现一个ajax脚本来获取数据。 目前,我已经实现了系统,可以使用Teepluss主题和搜索工具处理路径,控制器,视图。

我认为有一种更简单的方法可以使用MVC模式与Laravel一起实现这个插件。

有了这条线,我就拥有了我所需要的东西:

My controller
public function index()
{
$data = Client::orderBy('created_at', 'desc')->paginate(50);
$theme = Theme::uses('mytheme');       
$view = array(
    'name' => 'Teepluss',
    'data' => $data,
);

return $theme->scope('clients.index', $view)->render();
}


My view
//-- Table head here

@foreach($data->getCollection()->all() as $value)
//-- Table and data here
@endforeach

//-- Pagination links
{{ $data->appends(Request::except('page'))->links() }}

没有500错误,获取所有数据,分页工作正常。当然,我暂时放弃了DataTables插件的其他功能......

无论如何,非常感谢你!