douyue8685 2016-08-14 21:47
浏览 48
已采纳

对象父对象是$ object-> save(); $ this-> parent-> parent-> ... === $ this

First of all, sorry if the title is a little bit vague but it's the best I could come up with.

My problem: I have several tasks, each task can have subtasks. When a task is created it sets the finished_at field in the DB in the method recursiveParentUpdater(). For some reason my new task after saving is his own parent (but not in the database, still NULL).

Eg.

$task = new Task;
// set my properties
$task->save(); // let's say ID = 5

$task->parent->parent->parent->...->id === 5 // I have no idea why this happens

Then the $task->recursiveParentUpdater() uses $this->parent to get itself and screw it all up. This only happens when a new task is created, when deleting there is no more $task to parent itself.

It all used to work fine (local and shared hosting), 2 days later without having touched it I encountered this problem (only on shared hosting, local still no problems). My Debian machine is still running PHP5.6, shared-host supports 5.6 and 7 but it changes nothing.

My database schema UPDATED (added 'show create table tasks')

Schema::create('tasks', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->string('description')->nullable();
        $table->integer('parent_id')->unsigned()->nullable();
        $table->integer('user_id')->unsigned()->nullable();
        $table->date('deadline_date')->nullable()->default(null);
        $table->time('deadline_time')->nullable()->default(null);
        $table->datetime('finished_at')->nullable()->default(null);
        $table->timestamps();

        $table->foreign('parent_id')->references('id')->on('tasks')->onUpdate('cascade')->onDelete('cascade');
        $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
    });

or

 tasks| CREATE TABLE `tasks` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`parent_id` int(10) unsigned DEFAULT NULL,
`user_id` int(10) unsigned DEFAULT NULL,
`deadline_date` date DEFAULT NULL,
`deadline_time` time DEFAULT NULL,
`finished_at` datetime DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `tasks_parent_id_foreign` (`parent_id`),
KEY `tasks_user_id_foreign` (`user_id`),
CONSTRAINT `tasks_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `tasks_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=337 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

My model (parts that are relevant)

public function user() {
    return $this->belongsTo('App\User');
}

public function children() {
    return $this->hasMany('App\Task', 'parent_id', 'id');
}

public function parent() {
    return $this->belongsTo('App\Task');
}

public function hasParent() {
    return (!is_null($this->parent)) ? true : false;
}

public function hasChildren() {
    return (count($this->children) > 0) ? true : false;
}

public function updateParentFinishedStatus() {
    function recursiveParentUpdater($task) {
        if ($task->hasParent()) {
            $task->parent->setFinishedAt(date('d-m-Y H:i:s'));

            foreach ($task->parent->children as $child) {
                if (!$child->isFinished()) {
                    $task->parent->setFinishedAt(null);
                    break;
                }
            }
            $task->parent->save();

            if ($task->parent->hasParent()) recursiveParentUpdater($task->parent);
        }
    }

    recursiveParentUpdater($this);
}

My controller

public function postCreate(Request $request) {
    $this->validate($request, [
        'title' => 'string|required',
        'description' => 'string',
        'ptid' => 'integer|exists:tasks,id',
        'deadline_date' => 'date|after:yesterday|required_with:deadline_time',
        'deadline_time' => 'dateformat:H:i',
    ]);

    $task = new Task;
    $task->setTitle($request->get('title'));
    $task->setDescription($request->get('description'));
    $task->setDeadline($request->get('deadline_date'), $request->get('deadline_time'));

    if (!empty($request->get('ptid'))) {
        $task->parent()->associate($request->get('ptid'));
    }

    $task->user()->associate(Auth::user());

    $task->save();

    $task->updateParentFinishedStatus();

    return redirect()->back();
}

public function getDelete(Request $request) {
    $this->validate($request, [
        'tid' => 'integer|required|exists:tasks,id',
    ]);

    $task = Task::where('id', $request->get('tid'))->where('user_id', Auth::user()->id)->first();

    $task->delete();

    $task->updateParentFinishedStatus();

    return redirect()->back();
}
  • 写回答

1条回答 默认 最新

  • duanganleng0577 2016-08-15 18:13
    关注

    I am still not sure why it was a problem on the host and not on my local machine, but this what fixed it.
    I changed this line of code

    public function hasParent() {
        return (!is_null($this->parent)) ? true : false;
    }
    

    to

    public function hasParent() {
        return (!is_null($this->parent_id)) ? true : false;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料