EllisLab text mark
Advanced Search
1 of 2
1
   
I’m at a standstill….need help with controllers (theory)
Posted: 29 August 2008 03:34 PM
Joined: 2007-12-20
133 posts

I feel like I’m beating a dead horse but I’m stuck so here goes.  I’ve asked questions about controllers in these forums before and while I get good suggestions, I still am confused on the subject.  I’m very comfortable with models and views.  To me those are easy.  But controllers still mystify me, because there really is no best practice to creating them.

On one hand, it seems much easier to design your controllers with a specific view in mind.  One controller per view.  That seems right, but only because I come from a spaghetti code background where the controller was nothing more than a snippet at the top of the view file. What it did was allow me to keep the controller very small and very focused.

On the other hand, I could have a “user” controller that does many things.  Only thing is, at what point does it stop growing.  At least when you are using a one controller per view scenario it keeps your focus small and close to that particular view, so the view decides how that particular controller grows.

I use to design by user interface, letting the views tell me what needed to be in the controller but I really want to be more clean and structured and that is why I’ve been working with CI.

I just get confused, because view-centric design seems easy but looking at controllers in terms of objects per say almost makes me think of each controller as a little app in itself that does many things. Like user/add, user/edit, user/delete, user/profile, user/login, user/logout.  At what point do you stop and say wait a minute, why have lots of functionality in one large controller class (which will keep growing with time) when all you need is one method for one view, but you are loading in all that extra controller code that won’t be used on that particular request.  It just seems to me that by grouping things that might seem logical at first into one controller, down the road it would have been better to be small and discrete.

Maybe I’m just not understanding the approach and why it’s good to have all these different methods in one controller.  I tend to think in terms of user interface and that drove my design and kept my controllers very narrow and focused (albeit spaghetti code).

For me it comes down to the following scenarios.

1) Design with one controller per view and keep things small and discrete.  It would be nice to hear from someone that put this into practice and find out how they liked this philosophy.

2) Design based off objects which normally means looking at your database and creating a controller for each “object” and putting all the functions that can manipulate that object in one controller.  Possibly spread across a couple controllers I guess, but to me that’s when it gets fishy because I don’t think using the model is a good way to represent how your application should be divided up.

3) Create controllers based on the way you logically want to break up your application, that really has nothing to do with how the model is setup.  Looking at it through a URL perspective maybe and how to group things together.

The second scenario is where I have the most trouble, because I feel like controllers can easily lose scope and become not what they were intended, like little apps themselves.  I’m ready for someones $0.02 on the subject.

 
Posted: 29 August 2008 05:27 PM   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2008-05-28
682 posts

The thing with MVC and CI is that it’s all very loose. You really can chose which way you want to go with your controllers.

Personally, I break them up according to scenario three. I analyse the website I’m about to make and see how big it’s gonna be.

So far, I usually put the frontend off a website in one controller (mind you, haven’t done very large sites yet) and put the backend functionality in multiple controllers.

You say you’re afraid your controllers will grow beyond what you intended them to be. I say, don’t let them. Think, analyse and plan your application before you start coding it and make your controllers so you’re comfortable with them. If you want to put everything in one and you’re okay with it, great! If you feel you want separation, put everything in a separate one.

 Signature 

Bramme.net webdevelopment
If I had a nickel for every time someone told me that my idea for melting down coins to make a giant robotic parrot was a bad idea, I would have one kicka$$ giant robotic parrot.

 
Posted: 29 August 2008 08:37 PM   [ # 2 ]   [ Rating: 0 ]
Joined: 2007-12-20
133 posts

That’s part of my problem, that I have been planning for too long.  I’m ready to be coding already, but I can’t get past this dilemma.  I almost decided to code the app with two sub folders, one for admin and another for a reporting component.  The public accessible stuff would be in the root.  The only problem with this that I have screens that need to be shared between all the users, so this lead me to breaking the app down further piece by piece, to finally I’ve just wondered whether the one controller per view is the way to go.

 
Posted: 29 August 2008 08:39 PM   [ # 3 ]   [ Rating: 0 ]
Joined: 2007-12-20
133 posts

When I say one controller per view, i want to clarify, that obviously for a crud screen…it only makes sense to have one controller file.  Say…customer/add, customer/edit, customer/delete would all be within the customer controller.  Obviously the add/edit view would be used for both and delete would not have a view, so that nicely fits.  It’s almost like the controller i envision is more of a page controller, not a bloated little app all it’s own if that makes sense.

 
Posted: 29 August 2008 10:26 PM   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2007-02-06
743 posts

You’re not getting a lot of response, probably because the answer is personal choice. I don’t think anyone wants to force their personal preferences on you. For what it’s worth, I use 1 controller per view almost exclusively. I name a controller and its corresponding view identically. Better organization and less code to load.

 Signature 

“I am the terror that flaps in the night”

 
Posted: 30 August 2008 01:01 AM   [ # 5 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

This comes up all the time. And I’m not afraid to make a suggestion, especially since I’m not going to force a specification onto you. It’s just a conversation, after all.

One day, Request comes to town and it asks for a specific blog post.

It is greeted by the Blog controller, who makes sure everything checks out and passes the params that Request has brought along to Blog_model.

Blog_model goes to the database in the back and returns with a post.

Blog controller takes the pieces Blog_model returned and then worked with Views to piece it all together.

Finally, Request ended up with a nice package to send back to the Client.

* * * * * * * * * * * * * * * * * * * * * * * * * * * *

Okay, so that might seem a bit pejorative to you, but the point I’m trying to make is that each piece is sort of an actor in a little scene. The controller is sort of the concierge for the HTTP request. In the scenario above, the controller was responsible for handling a blog object. The process was pretty simple, but imagine a Cart controller that was taking an order. It would have to build the order, generate the total, validate the payment, pass the payment to the gateway, handle the response, save the order, email the customer, email the store owner, and generate a receipt for the user, among many other things.

Controllers can sometimes be thought of object handlers, one for each unique object of your application. Blog posts, tasks, products, carts, categories, users: These are the kind of “objects” that would probably each get it’s own controller.

So the point is, sometimes the Controller has a lot to do, so it’s bound to get bloated in some cases. Models retrieve and format data, whether the data comes from a database, flatfile, or web service call. And a View formats the objects for display.

Controller: Handle request for objects (or actions on objects).
Model: Retrieve objects.
View: Format objects for display.

Just don’t mix those roles, and you should be safe.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 30 August 2008 12:49 PM   [ # 6 ]   [ Rating: 0 ]
Joined: 2007-12-20
133 posts

@Rick Jolly

Yeah, I realize that.  I appreciate your insight and I’m really leaning the way of one controller per view for the reasons that you suggested, better organization and less code to load.

@Colin Williams

I totally understand your examples and realize what your saying.  My problem with thinking of controllers as object handlers begins to break down when I think about the “cart” controller example you used.  I realize how large a checkout method in the cart controller might be as it should be.  Like you said, it does a lot of stuff.  But, to me, it would be better to actually have a “checkout” controller, because it just seems a waste to have all those other methods in the cart controller that have to get loaded that won’t be used on that request.  It would seem that the only things that could be shared between the different methods in a cart controller would be possibly a cart_model and maybe a couple libraries, but other than that, all the methods would probably stand on their own.

@anyone

It seems that sometimes the controller can be abused and used strictly for grouping somewhat related functions.  Maybe in my one controller per view thinking, I should look at putting controllers into subfolders as my way of grouping related functions, instead of throwing everything in one controller file.

 
Posted: 30 August 2008 01:09 PM   [ # 7 ]   [ Rating: 0 ]
Avatar
Joined: 2007-06-10
2937 posts

Rick Jolly makes a good point and MVC itself is a fairly 1:1 Controller View relationship when you break it down. The fact that we all create smaller parts of a larger View in a single Controller is merely squeezing Controller + View snippets into one larger file.

You could always look into using Modular Extensions, it enhances CI by allowing Controller, Model and View parts to be seperated into modules and used in true MVC style.

 Signature 

URI Language Identifier | Modular Extensions - HMVC | View Object | Widget plugin | Access Control library

 
Posted: 30 August 2008 02:33 PM   [ # 8 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

I realize how large a checkout method in the cart controller might be as it should be.  Like you said, it does a lot of stuff.  But, to me, it would be better to actually have a “checkout” controller, because it just seems a waste to have all those other methods in the cart controller that have to get loaded that won’t be used on that request.

Well, it can be argued all day long, but your almost always controlling an action on an object. So a checkout controller is an action-focused controller, and a cart is an object-focused controller. I suppose you can mix and match as you see fit. You obviously do have a good clue of how you prefer to organize your app. I think there are many right ways to do things any many wrong ways to do things, and a few gray areas. What a shocker! tongue wink

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 30 August 2008 02:46 PM   [ # 9 ]   [ Rating: 0 ]
Joined: 2007-12-20
133 posts
Colin Williams - 30 August 2008 06:33 PM

I realize how large a checkout method in the cart controller might be as it should be.  Like you said, it does a lot of stuff.  But, to me, it would be better to actually have a “checkout” controller, because it just seems a waste to have all those other methods in the cart controller that have to get loaded that won’t be used on that request.

Well, it can be argued all day long, but your almost always controlling an action on an object. So a checkout controller is an action-focused controller, and a cart is an object-focused controller. I suppose you can mix and match as you see fit. You obviously do have a good clue of how you prefer to organize your app. I think there are many right ways to do things any many wrong ways to do things, and a few gray areas. What a shocker! tongue wink

I see what your saying and yes there is a lot of gray.  As an example, say I have several forms that a person needs to fill out that produces a “plan”.  Each of these forms hit up to 3 tables of information.  So there is no direct correlation between one table per controller or whatever.  If I were doing object focused controllers, would I have a “plan” controller and each form would then be an action within that controller, even though technically each form uses different tables and really have nothing to do with one another, other than they are grouped together because they eventually make this “plan”.  Or is that not exactly the object focused controller that you are talking about?  Because obviously I have no plan table in my database, there are many tables in my database that eventually becomes the plan.  Is this when the idea of a “plan” object focused controller breaks down a bit and I need to look at smaller controllers?

Ah, flexibility and freedom are great, once you know what to do with them!  smile

 
Posted: 30 August 2008 02:58 PM   [ # 10 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

Because obviously I have no plan table in my database, there are many tables in my database that eventually becomes the plan.  Is this when the idea of a “plan” object focused controller breaks down a bit and I need to look at smaller controllers?

So, a plan is still an object, it’s just represented by several tables. An object need not map to a single table. Models need not even map to a single table.

Do you need to break that down into smaller controllers? I don’t necessarily think so, unless there are enough independent actions to take on each piece of a plan, or there will be in a later phase. MVC is an organizational pattern, so designing your app can be a bit like information architecture. Ask yourself, “6 months from now, when I need to update the ‘plan’ system, where is the most logical place I or another programmer would look?”

This is partly why documenting as you build is a good idea because every time you find yourself adding another caveat to an explaination, you discover areas that could be organized more intuitively.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 30 August 2008 03:08 PM   [ # 11 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

I actually have a similar real-world scenario happening now. I’m adding a feature to site through which users can create and manage “bike checks” and share these with other users, embed them in social networking sites, etc.

The main object is a bike. A bike is made up of bike parts and some meta info. Bike parts are made up of bike manufacturers and bike part types. I’ve got a lot of different objects coming together to make one bike object.

I’ve settled on breaking it down into several controllers, all nested under bike:

bike
bike/add
bike/edit
bike/delete
bike/view

bike/part/view
bike/part/add
bike/part/edit
bike/part/delete

bike/manufacturer/add
...

bike/part_type/add
...

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 30 August 2008 04:06 PM   [ # 12 ]   [ Rating: 0 ]
Joined: 2007-12-20
133 posts
Colin Williams - 30 August 2008 07:08 PM

I actually have a similar real-world scenario happening now. I’m adding a feature to site through which users can create and manage “bike checks” and share these with other users, embed them in social networking sites, etc.

The main object is a bike. A bike is made up of bike parts and some meta info. Bike parts are made up of bike manufacturers and bike part types. I’ve got a lot of different objects coming together to make one bike object.

I’ve settled on breaking it down into several controllers, all nested under bike:

bike
bike/add
bike/edit
bike/delete
bike/view

bike/part/view
bike/part/add
bike/part/edit
bike/part/delete

bike/manufacturer/add
...

bike/part_type/add
...

Does that mean your using controller subfolders?  you have a bike controller, but then you have a bike subfolder with a part controller..and manufacturer controller??

 
Posted: 30 August 2008 04:10 PM   [ # 13 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

Correct.

app/controllers/bike.php
app/controllers/bike/part.php
app/controllers/bike/manufacturer.php

More and more I don’t like how bike.php falls out of the other group, so I’ve considered moving it to app/controllers/bike/core.php, but I equally don’t like setting up routing when it isn’t absolutely necessary.. IDK, still up in the air about it.

I might also mention that I have one Bike_model, prototyped like:

Bike_model
    save_bike
()
    
get_bike()
    
save_part()
    
get_part()
    
save_manufacturer()
    
get_manufacturer()
    
[...

 
To me, it’s nice having that as one unit.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 30 August 2008 04:12 PM   [ # 14 ]   [ Rating: 0 ]
Joined: 2007-12-20
133 posts

Gotcha!  I think that is what will help me find that happy medium between keeping things grouped together, but being able to keep my controllers small and discrete.  Thanks a lot for your input Colin.  It has been very helpful.

 
Posted: 06 September 2008 02:06 PM   [ # 15 ]   [ Rating: 0 ]
Joined: 2007-04-24
132 posts

@Colin Williams - I am curious about how you group the views for your controllers?

app/views/bike/add.php
app/views/bike/view.php
..
app/views/bike/part/add.php
app/views/bike/part/view.php
..
app/views/bike/manufacturer/add.php
app/views/bike/manufacturer/view.php
etc..

 Signature 

CI Bookmarks

 
1 of 2
1