Laravel保存了有序模型的有序列表

Jas*_*onK 12 drag-and-drop model sorted laravel eloquent

我正在创建一个食物菜单,管理员可以通过拖放来订购/排序.此菜单包含多个类别(ProductCategory)和产品(Product).

我在客户端使用HTML5Sortable来允许嵌套的d&d.标记非常简单:

<div class="categories">
    @foreach($categories as $category)
    <div class="category">
        @foreach($category->products as $product)
        <div class="products">
            <div class=""product" data=id="{{ $product->id }}">
                 {{ $product->name }}
            </div>
        </div><!-- /products !-->
        @endforeach
    </div><!-- /category !-->
    @endforeach
</div>
Run Code Online (Sandbox Code Playgroud)

和相应的javascript:

$('.categories').sortable({
    items: '.category'
});
$('.products').sortable({
    items: '.product'
});

// Will be called when the user is done repositioning the products and categories
function getOrderedList() {
    var data = {};

    $('.categories').find('.category').map(function(i) {
        var category = $(this);
        data[i] = {};
        data[i].id = category.data('id');
        data[i].products = category.find('.product').map(function() {
            return $(this).data('id');
        }).get();
    });

    data = JSON.stringify(data); // Send data to server
}
Run Code Online (Sandbox Code Playgroud)

该函数getOrderedList将一个JSON字符串发送回Laravel,其中包含已排序的类别ID和产品ID:

{"0":{"id":1,"products":[2,3,1,4,5,6,7,8,9,10]},"1":{"id":2,"products":[11,12,13,14]},"2":{"id":3,"products":[15,16,17,18]}}
Run Code Online (Sandbox Code Playgroud)

我如何在后端进行这项工作?我想我必须将这个数组存储在数据库的某个地方,然后通过id找到并订购模型?

简而言之:什么是分类(嵌套)模型(在Laravel中)的清晰灵活的解决方案?

UX *_*abs 7

常见的约定是权重,在产品表上添加一个名为(Int)Weight的字段,用于定义项目的顺序.

一旦订单发生变化,您只需更新权重字段.

检索项目时,按权重对其进行排序.

它变得类似于数组

Id        Name            Weight
01        'product 1'     2
02        'product 2'     0
03        'product 3'     1
Run Code Online (Sandbox Code Playgroud)

当你按重量订购时,你会得到

product 2
product 3
product 1
Run Code Online (Sandbox Code Playgroud)

它类似于数组,因为

$products[0] = 'product 2'
$products[1] = 'product 3'
$products[2] = 'product 1'
Run Code Online (Sandbox Code Playgroud)

请注意,如果要使其更具动态性,可以创建一个可满足多个模型的多态模型.

请参阅https://laravel.com/docs/5.1/eloquent-relationships#many-to-many-polymorphic-relations

多态关系的例子

创建表权重(迁移示例)

$table->increments('id');
$table->integer('value');
$table->integer('weightable_id')->unsigned();
$table->string('weightable_type');
Run Code Online (Sandbox Code Playgroud)

创建模型权

class Weight extends Eloquent
{
    public function weightable()
    {
        return $this->morphTo();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在与任何其他模型

class Products extends Eloquent
{
    ...
    public function weight()
    {
        return $this->morphOne(Weight::class);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样您就可以将该方法添加到您想要的任何模型中,然后您可以使用它对模型进行排序.

PS确保使用它的任何模型在创建模型后立即创建该关系

我不建议使用这种方法,如果你在Products表中明确定义权重字段会更好,我知道你希望你的代码有多大动态,但是一切都需要付出代价

性能下降,一旦建立多态关系,可视化代码并不容易,更像是开始使用Jumps而不是函数