Laravel在数据库中订购商品

时间:2015-07-11 16:36:49

标签: php database laravel model

您好我使用Laravel和自定义CMS将存储在CMS中的某些标签同步到数据库中。这个功能很好。但是我想在将它们插入数据库时​​以数字方式为它们设置顺序,如果将新的数据库同步到数据库中,我希望将其作为最后一个值添加到数据库中,即如果新项目存在12个项目将在order列中添加为值12(因为0将是第一个值)。我希望在不重置现有订单值的情况下完成此操作。

这就是我在我的存储库中的内容:

public function sync()
{

    $tags = $this->client->fetchTags('Status');
    $updated = $this->update_tasks($tags);        
    // remove the rest of the statuses
    \Status::whereNotIn('id',$updated->lists('id'))->delete();
}

/**
 * Save any tags to the local DB;
 * @param $tag
 */
public function update_tags($tags)
{


    $return = [];
    foreach ($tags as $tag) {
        $return[] = $tag->id;    
    }


    $local  = \Status::whereIn('cms_tag_id',$return)->get()->toIndexedArray('cms_tag_id');

    foreach ($tags as $tag) {

        if (isset($local[$tag->id]))
        {
            $local_doc = $local[$tag->id];
        } 
        else
        {
            $local_doc = new \Status;
        }
        $local_doc->updateFromCMS($tag);
        $uids[] = $local_doc->cms_tag_id;
    }
    return \Status::whereIn('cms_tag_id',array_unique($uids));
}

然后在我的模型中我有这个: Status.php

public function updateFromCMS($tag)
{
    $i = 0;
    $this->cms_tag_id = $tag->id;
    $this->cms_tag_name = $tag->name;
    $this->order = $i++;
    $this->save();
    return $this;
}

但是,这会将order列中的所有值添加为零,这是不合需要的,并且找到的任何新值也会添加为零值。我有什么想法可以保存这个命令,例如:0-100?

更新

根据@insanebits的说明,我已将模型更改为以下内容:

public function updateFromCMS($tag)
{
    $i = Status::orderBy('order', 'DESC')->pluck('order');
    $this->cms_tag_id = $tag->id;
    $this->cms_tag_name = $tag->name;
    $this->order = $i+1;
    $this->save();
    return $this;
}

但是现在这会更改所有行的订单值。即,如果最高值为5,那么0的值将被设置为6,然后一切都将其值增加1.因此,设置的顺序将丢失。我有什么想法我做错了吗?

2 个答案:

答案 0 :(得分:2)

如果您需要更新现有代码的ID和名称,则只应为新代码调用updateFromCMS

foreach ($tags as $tag) {

    if (isset($local[$tag->id]))
    {
        $local_doc = $local[$tag->id];
    } 
    else
    {
        $local_doc = new \Status;
        $local_doc->updateFromCMS($tag); //only for new tags
    }

    $uids[] = $local_doc->cms_tag_id;
}

如果您需要更新现有标签的ID和名称,请向updateFromCMS添加一个参数,告诉它是否更改订单:

public function updateFromCMS($tag,$update_order)
{    
    $this->cms_tag_id = $tag->id;
    $this->cms_tag_name = $tag->name;

    if($update_order) {
        $i = Status::orderBy('order', 'DESC')->pluck('order');
        $this->order = $i+1;
    }

    $this->save();
    return $this;
}

按以下方式更改foreach

foreach ($tags as $tag) {

    if (isset($local[$tag->id]))
    {
        $local_doc = $local[$tag->id];
        $local_doc->updateFromCMS($tag,false); //don't update order
    } 
    else
    {
        $local_doc = new \Status;
        $local_doc->updateFromCMS($tag,true); //update order
    }

    $uids[] = $local_doc->cms_tag_id;
}

答案 1 :(得分:-1)

如果您将数据库中的order列设置为autoincrement,该怎么办?例如您的迁移可能如下所示:

class CreateStatusTable extends Migration {

    public function up() {
        Schema::create('status', function (Blueprint $table) {
            $table->increments('id');
            $table->increments('order');
            /* ... your other fields ... */
            $table->timestamps();
        }
    }
}

这样您就不必担心在模型中明确设置order字段了,而且您知道每次向数据库添加新的Status时,总会分配给它下一个最高整数值。

或者,您可以完全删除order列,并依赖于您知道将成为整数的id字段,并在添加新的Status行时按顺序递增到DB。

我可以看到这种方法的唯一潜在缺点是,如果您删除了Status,最终会有一些行具有idorder的非连续值,即如果表格中有5个项目并且您使用id = 3删除了该项目,则最终会得到4个id值为0, 1, 2, 4的项目。但是,订单将始终保留,代码如下:

$statuses = Status::orderBy('id', 'DESC');

将始终按照您将其添加到数据库的原始顺序返回Status个对象数组。

相关问题