Support the ongoing development of Laravel.io →
Requests Input Eloquent

WARNING: NASTY PROCEDURAL CODE AHEAD.

Let's say I have an ajaxified to-do list app. I have this route:

Route::post('tasks/delete', 'TasksController@delete');

My goal is to have this:

class TasksController extends BaseController {

	protected $taskManager;

	public function __construct(TaskManager $taskManager)
	{
		 $this->taskManager = $taskManager;
	}

	public function delete()
	{
		/* I want something like this from the AJAX POST
		$ids = array(
			'1' => array(1, 8, 2),
			'4' => array(5, 7)
		);*/

		$this->tasks->deleteBy(Input::get('ids'));
	}

}

Have some class doing the work:

class TaskManager {

	public function deleteBy($ids)
	{
		foreach ($ids as $index => $task)
		{
			foreach ($task as $list_id => $task_id)
			{
				$lists = User::with('lists.tasks')->find(Auth::user()->id)->lists->find($list_id);

				if ($mdl_lists)
				{
					$mdl_lists->tasks()->find($task_id)->delete();
				}
			}
		}
	}
}

Then I have this in my script.js:

var tasks = {
	ids: []
};
$(document).on('click', '.list > li', function() {

	// Grab the id from both the selected task
	// and the list
	var list_id   = $(this).parent().attr('data-list-id');
	var task_id = $(this).attr('data-task-id');

	// Dynamically setting the name of the property
	var task = {};
	task[list_id] = task_id;
	tasks.ids.push(task);

});

$(document).on('click', '.delete-tasks', function() {

	$.ajax({
		url: 'tasks/delete',
		type: 'POST',
		data: JSON.stringify(tasks),
		contentType: 'application/json',
		success: function(response) {

			// for each task, remove
			for (var i = 0; i < tasks.ids.length; i++) {
				$('.list li[data-task-id=' + tasks.ids[i][Object.keys(tasks.ids[i])[0]] + ']').remove();
			}
		}
	});

});

Reasons for some of that code:

Why an empty array inside the tasks object literal?

Well, I don't know how to grab tasks from Laravel (Input::get('tasks')), so I'm kinda forced to use the ids array as a wrapper.

Why all that eager loading when you could just do Task::delete($ids);?

Security. I want to make sure you can only delete your tasks. If someone would change the task-id via HTML and then send the request.. Well, bad luck for another user.

Why the if() after the eager loading part?

Maybe someone changed the list-id on the HTML, so I'm checking if it's empty, that would mean it's not his list.

Why the double foreach?

As you can see in TaskController, I'm expecting an array in that format because of the way the task manager is doing the work. In '1' => array(1, 8, 2), the key is the list-id and the array contains the task-ids. Ideally that's what I would want, but due to my limited knowledge in Javascript, what I end up having is '1' => 1, '1' => 8, '1' => 2. So the first foreach is to get inside the array of arrays, and the second one is where the works gets done.

I know there has to be a better way to this. Can someone help me refactor this code? I want to find better ways to do specially what I answer in those questions.

Last updated 3 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.