2016-08-14 4 views
0

まずは、タイトルがやや曖昧だと申し訳ありませんが、私が思いつくのは最高です。

私の問題: 私はいくつかのタスクを持って、各タスクはサブタスクを持つことができます。 タスクが作成されると、recursiveParentUpdater()メソッドでDBのfinished_atフィールドが設定されます。何らかの理由で、保存した後の私の新しいタスクは、自分の親です(しかし、データベースではなく、まだNULLです)。

例:

$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 

$ task-> recursiveParentUpdater()は、$ this-> parentを使って自分自身を取得し、すべてをスクープします。 これは、新しいタスクが作成されたときに、それ自身を親にする$タスクが削除されていない場合にのみ発生します。

2日後にこの問題が発生しました(共有ホスティングのみ、ローカルでは問題ありません)。 私のDebianマシンはまだPHP5.6を実行していますが、共有ホストは5.6と7をサポートしていますが、何も変わりません。

マイデータベーススキーママイコントローラ

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 | 

マイモデル(関連する部分)

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); 
} 

UPDATED(追加 'テーブルタスクを作成ショー')

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(); 
} 
+0

にこのコード行を変更しましたが、これまでに作成したタスクの 'id'として' parent_id'を設定しているようです。 – Sherif

答えて

0

私はそれがなぜホスト上で問題であったのか、私のローカルマシン上で問題ではないのかまだ分かりませんが、これを修正しました。
は、私たちが問題を再現しようとすることができるように、あなたが代わりにSQLのようにあなたのテーブルのための実際のスキーマを提供し、関連するデータが含まれている必要があり

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

public function hasParent() { 
    return (!is_null($this->parent_id)) ? true : false; 
} 
関連する問題