您好我使用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.因此,设置的顺序将丢失。我有什么想法我做错了吗?
答案 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
,最终会有一些行具有id
或order
的非连续值,即如果表格中有5个项目并且您使用id = 3
删除了该项目,则最终会得到4个id
值为0, 1, 2, 4
的项目。但是,订单将始终保留,代码如下:
$statuses = Status::orderBy('id', 'DESC');
将始终按照您将其添加到数据库的原始顺序返回Status
个对象数组。