【问题标题】:How can I use Eager Loading with Yajra Datatables and Dimsav Translatable in Laravel 5.2如何在 Laravel 5.2 中将 Eager Loading 与 Yajra 数据表和 Dimsav Translatable 一起使用
【发布时间】:2016-03-21 12:18:37
【问题描述】:

我正在使用 yajra/laravel-datatables 和 dimsav/laravel-translatable 创建角色表。

数据表结构如下。 角色表迁移:

Schema::create('roles', function (Blueprint $table) {
    $table->increments('id');
    $table->softDeletes();
    $table->timestamps();
});

角色转换表迁移:

Schema::create('role_translations', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('role_id')->unsigned();
    $table->string('name')->index();
    $table->string('locale')->index();

    $table->unique(['role_id', 'name', 'locale']);
    $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
});

现在我正在控制器上执行此操作...

public function indexData()
{
    $roles = Role::join('role_translations', 'roles.id', '=', 'role_translations.role_id')
        ->select(['roles.id', 'role_translations.name', 'roles.created_at', 'roles.updated_at'])
        ->groupBy('roles.id');

...这在视图中(数据表初始化和常规设置在一个通用 js 文件中完成,特定设置作为 HTML 属性传递)...

<table class="table table-striped table-bordered" data-table data-ajax="{{ url('/admin/role/index-data') }}" data-responsive="true">
    <thead>
        <tr>
            <th data-priority="1">{{ trans('messages.name') }}</th>
            <th>{{ trans('messages.created') }}</th>
            <th>{{ trans('messages.modified') }}</th>
            <th data-priority="1" data-sortable="false" data-class-name="actions">{{ trans('messages.actions') }}</th>
        </tr>
    </thead>
</table>

它有效,但我对查询中的所有这些连接感到不舒服,我想做类似的事情

$roles = Role::with('translation')->select(['roles.id', 'role_translations.name', 'roles.created_at', 'roles.updated_at'])

但我没有运气。

【问题讨论】:

    标签: datatables laravel-5.2


    【解决方案1】:

    这是我的预加载工作示例。希望对你有帮助

    //控制器查询

    $medicine  = Medicine::with(['manufacturer','doseageForm','measureUnit','supplier'])
                ->select(['id','product_name','generic_name','product_class','manufacturer_id', 
                          'doseage_form_id','measure_unit_id','strenght','status']);
    
    return Datatables::of($medicine)
            ->editColumn('status', function($medicine){
                return (($medicine->status == 1)?"Active":"Deactive");
            })
            ->editColumn('manufacturer_id', function($medicine){
    
                $manufacturer_name   =   $medicine->manufacturer->name;
                return $manufacturer_name;
            })
            ->editColumn('product_name', function($medicine){
                return 
                    $medicine->product_name.", ".
                        $medicine->doseageForm->name.", ".
                        $medicine->strenght.$medicine->measureUnit->name;
            })
            ->addColumn('supplier',function($medicine){
    
                if($medicine->supplier->count() > 0){
                    return $medicine->supplier->first()->qualified_person;
                }else{
                    return '---';
                }
            })
            ->addColumn('actions', function($medicine){
    
                $edit_route =   route('medicine-edit',['id'=>$medicine->id ]);
                $del_route  =   route("ajax-delete",["type"=>"medicine","id"=>$medicine->id ]);
    
                $status     =   (($medicine->status == 1)?
                                    '<a href="" class="btn btn-xs btn-warning"><i class="fa fa-eye"></i></a>'
                                    :
                                    '<a href="" class="btn btn-xs btn-warning"><i class="fa fa-eye-slash"></i></a>'
                                );
    
                $html       =   '<div class="btn-group">
                                    '.$status.'
                                    <a href="'.$edit_route.'" class="btn btn-xs btn-primary" alt="edit"><i class="fa fa-pencil"></i></a>
                                    <a href="'.$del_route.'" data-target="#ajax_delete" alt="delete" data-toggle="modal" class="btn btn-xs btn-danger">
                                        <i class="fa fa-trash-o"></i>
                                    </a>
                                </div>';
    
                return $html;
            })
            ->make(true);
    

    我的查看代码是

    <table class="table table-bordered table-striped table-condensed flip-content" id="medicine">
        <thead class="flip-content">
            <tr>
                <th>Medicine</th>
                <th>Generic</th>
                <th>Class</th>
                <th>Manufacturer</th>
                <th>Supplier</th>
                <th>Actions</th>
            </tr>
        </thead>
    </table>
    

    我的数据表 JS 脚本

    <script type="text/javascript">
        var oTable;
    
        $(document).ready(function() {
            oTable = $('#medicine').DataTable({
                "responsive": true,
                "processing": true,
                "serverSide": true,
                "ajax": "{!!route('medicine-data')!!}",
                "columns": [
                    {data: 'product_name',       name: 'product_name'},
                    {data: 'generic_name',       name: 'generic_name'},
                    {data: 'product_class',       name: 'product_class'},
                    {data: 'manufacturer_id',         name: 'manufacturer_id'},
                    {data: 'supplier',           name: 'supplier'},
                    {data: 'actions',            name: 'actions'},
                ]
            });                        
        });
    </script>
    

    【讨论】:

    • 我知道这行得通,但我无法使用 dimsav 可翻译包制作类似的东西。这个包建立了一对多的关系。在这种情况下,一个角色的名称字段有许多翻译。我想要做的是急切地加载翻译后的名称(在后备语言环境中),避免所有的连接。
    • 我没有收到您的上述评论?你能解释更多吗?你能告诉我你的角色关系以及你想如何显示它们吗?
    • 我的意思是我正在使用另一个包 dimsav translatable (github.com/dimsav/laravel-translatable) 来管理我的模型的翻译。与该包建立的关系在模型上并不明确。在我上面的示例中,在具有所有连接的控制器上,您可以看到 dimsav 可翻译使用的数据库结构。我想用后备语言环境急切地加载角色模型的翻译,而不是使用所有那些讨厌的连接。
    • 你能分享你的两个表结构吗?
    • 请更新您的表格结构,在您的问题中添加屏幕截图或列名称
    【解决方案2】:

    在角色模型中创建关系方法
    public function translation(){ return $this->hasMany("\App\Translation"); }

    然后像这样在你的 RoleController 中查询 $roles = Role::with('translation')-&gt;get();

    另外,您可以在翻译中添加条件 $roles = Role::with('translation',function($query){ return $query->where('locale','en'); })->get();

    或者关注这个 Laravel 文档https://laravel.com/docs/5.2/eloquent-relationships

    【讨论】:

      【解决方案3】:

      也许可以通过在 with() 中传递一个闭包函数来完成。

      看到这个答案https://stackoverflow.com/a/19921418/1061663

      【讨论】:

        猜你喜欢
        • 2017-09-07
        • 2017-09-17
        • 1970-01-01
        • 2014-10-22
        • 2016-10-05
        • 1970-01-01
        • 2016-10-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多