Controller Questions

Hi There

I’m new to Yii and MVC frameworks, but so far i’m enjyoying my Yii experience.

Currently as a test application to learn Yii i’m building myself a task manager which so far is working well. however i’m a little unsure as to whether i’m doing things correctly.

So the situation is that i have 3 tables, projects, jobs and tasks.

-> Project, which is the parent

-> Job , which is a child of project, can have many jobs for each project

-> Task, child of job, can have many tasks for each job.

In order to add a job they first have to select a project, then click "add job" and that will then add a job to the project.

likewise for a task, they need to choose a project, select a job, and then click "add task" that adds a task to the job.

Currently i have all my controller code in ProjectsController.php as they always need to have selected a project first before they can add a job. This is all working, however it strikes me that maybe the JobsController.php & TasksController.php should be handling the "Create" and "Update" calls when dealing with jobs and tasks.

Example code from my ProjectsController.php when adding a job to a project.




public function actionAddJob($id)

	{

		$project=$this->loadModel($id);

		$jobs=$this->newJob($project);

		$this->render('view/job/create',array(

			'model'=>$project,

			'jobs'=>$jobs,

		));

	}



and the newJob function




	protected function newJob($project)

	{

		$jobs=new Jobs;

		if(isset($_POST['ajax']) && $_POST['ajax']==='jobs-form')

		{

			echo CActiveForm::validate($jobs);

			Yii::app()->end();

		}

		if(isset($_POST['Jobs']))

		{

			$jobs->attributes=$_POST['Jobs'];

			if($project->addJob($jobs))

			{

				$this->redirect(array('viewjobs','id'=>$project->id));

			}

		}

		return $jobs;

	}



So the question is, is this the right way to do it, and if not what’s the best approach.

Hope that makes some sense :wink:

Thanks

The idea of “one controller for each and every model class” came from Ruby on Rails and its community where this REST/CRUD approach seems to be almost mandatory. In my opinion it’s often unnecessary and sometimes a sign of bad design. If Tasks and Jobs always belong to a Project (Project is an Aggregate Root in this case) then keep all code in ProjectsController.

When your application gets bigger and complex… one part can be used on different situations… in your case task and job can be used somewhere else…

then it’s easier to remember things like “task/create” - TaskController->actionCreate() then project/taskcreate - ProjectController->actionTaskcreate()

I agree on that.

I am new to Yii as well and the whole concept of MVC architecture.

Let us remember the basics of OOP and how each Class is an entity and should include its own data and logic. So mixing it all together does work but it lacks design, simplicity and it ignores some of the basic rules of OOP.

At the same level, why use MVC and not put everything together in one file.

If it is a project that you are going to be using in the future and it is more serious than a demo then my answer would be to split things up. If it is a demo or something to help you learn then don’t even bother although it would be a good practice for creating a habit.

Controllers aren’t objects (and surely not entities) in the strict sense of the word. They are just a bunch of functions grouped together where the class only serves as a namespace. One’s free to goup actions as needed.

good design != largest possible number of classes

thanks for the quick replies everyone, so the consensus is (i think)

that if the project is already selected it goes in ProjectsController->actionAddTask

but if i was to add a task independent of the project that would be TaskController->actionAddTask.

so essentially i’m doing it correctly at the moment. (i think)

I’d split the controllers, in order to have alla actions of job in the job controller and so on.

In the view of job, when you have to create a new task, I’d redirect to task/create with a get parameter for the job.

Essentially you are doing correctly in each case, but from my point of view, is better to leave the actions in the orginal controller.

I will agree with the fact that you don’t have to split everything up and call it good design.

That in my dictionary makes it a class, an entity, an object. Then again every class is just a bunch of functions.

You can also consider the fact that the Model(Jobs, Tasks) serves most of the data structure, so you can have the Controller managing the Jobs and the Tasks.

I ll agree with Zacharia, that it is kind of subjective and whichever way you do it it works, and it is correct. I prefer keeping things separately as well, and it depends on the scalability and reuse of the application.

We use different dictionaries.

I can’t agree more :)