CodeIgniter Forums

Full Version: Controller / View Relationship
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
1 to 1 or 1 to many, is the question in short.

I'm coming from an ASP.NET C# Web Forms environment where forms/pages that are related to a business function are kept in the same folder. Web Forms has good security based on folders and only allowing users belonging to the permitted roles to access the pages in that folder. Much of the code is held in classes so the code behind the forms themselves can be quite light. We end up a structure that like:

example.com/ (public interface and many, many pages)
example.com/accounts (Accounts Department 'home' page and menu, accessed by Accounts and Managers)
example.com/accounts/customerlist
example.com/accounts/customeredit
... plus 100 more.
example.com/manager (Managerial section 'home' page, only Managers allowed)
example.com/manager/stafflist
example.com/manager/rosters
... plus another 50 more.
etc, etc.

For my CodeIgniter project, I'd assumed that I would have one controller per functional area (accounts, manager, etc), each with their many views. Each function within the controller would load the model for it's view. As with our ASP.NET folders, only users in the permitted roles would be able to access the views controlled by this controller and that it would pretty much mirror the above from the user's point of view. I want to leave aside the advanced opportunities presented by routing at this stage. The users are happy with the structure above.

My concern is that my controllers may get too big. For example, the 'accounts' role needs to access around 100 different views. They need to be able to access and update information on customer, invoices, suppliers, inventory and many, many more. The other few roles have fewer forms, but the same concept.

However, if you go for a 1 to 1 relationship between controller and view, it seems a bit of an abstraction to me. You might as well just have the model code in classes and mix what happens in the controller in with the HTML in a plain old PHP page. Which is what happens now in the Webforms system.

Is it best practice to have one controller per role and allow it to manage dozens of views or should I go the Apple way and have one controller for every view. Something in between maybe?

Thanks for any opinions.
Simon
I'd do it the same way. Use an Account, Manager, ... etc controller and a function for each view. But there's no "best way".
See the CodeIgniter News Tutorial in the Users Guide.
(04-28-2017, 05:58 AM)donpwinston Wrote: [ -> ]I'd do it the same way. Use an Account, Manager, ... etc controller and a function for each view. But there's no "best way".

Thanks donpwinston, I think doing it this way would suit me, so that's good to hear.
(04-28-2017, 08:56 AM)InsiteFX Wrote: [ -> ]See the CodeIgniter News Tutorial in the Users Guide.

I followed the News tutorial a few months ago and built the application successfully. A couple of sections in the text are what got me thinking about my question initially. One describes the controller as being the glue, the center of the application, and that had me thinking that perhaps fewer controllers are better, perhaps just one even. The other section is where I'm not sure if confirmation bias comes in, as they have a new controller for the News view, but say this could have been in the original Pages controller and that also meant fewer is better to me.

Thanks for leading me back to the tutorial. I think I should go with a controller per functional group and risk them being bigger.
I would avoid though the big fat controller if I were you.

For instance suppose your page has the following options and content:

Code:
Manager Home page
Users
    List users
    Add user
    Edit user
Pages
    List pages
    Add page
    Edit page
Accounts
    List accounts
    Create account
    Edit account
Products
    Add product
    Edit product
    Manage images
Categories
    List categories
    Add category
    Edit category
Orders
    List orders
    Add orders
    Edit orders
Customers
    List customers
    Add customer
    Edit customer

With the page content for manager home page something like
Code:
Graphs
Latest activity
Overdue orders
New orders
Messages
Todo list

I would have the following controllers

Code:
manager (folder)
    Manager_home.php
    Users.php
    Pages.php
    Accounts.php
    Categories.php
    Orders.php
    Customers.php

And view structure

Code:
manager (folder)
    home_view.php
    users (folder)
       list_users_view.php
       add_user_view.php
       edit_user_view.php
    pages (folder)
       list_pages_view.php
       add_page_view.php
       edit_page_view.php
etc

So now, when you need to change the categories page in the manager, you would just be dealing with the categories.php controller, the categories models and libraries, and the page views in the manager/categories folder.

I also (these days) try to keep my controllers as thin as possible so the manager_home.php would look something like:

PHP Code:
<?php
defined
('BASEPATH') OR exit('No direct script access allowed');

class 
Test extends CI_Controller {

    public function 
index() {
       
// set variables
       
$page_data = array();
 
       
// load resources
       
$this->load->library('manager_library');
       
$this->load->library('permissions_library');
 
       
// check permissions
       
$this->permissions_library->get_permissions('manager_home');
 
       
// get data
       
$page_data['graph_data'] = $this->manager_library->get_graph_data();
       
$page_data['latest_activity'] = $this->manager_library->get_latest_activity();
       
$page_data['overdue_orders'] = $this->manager_library->get_overdue_orders();
       
$page_data['new_orders'] = $this->manager_library->get_new_orders();
       
$page_data['messages'] = $this->manager_library->get_messages();
       
$page_data['todo_list'] = $this->manager_library->get_todo_list();
 
       
// load views
       
$this->load->view('common/admin_header_view');
       
$this->load->view('manager/home_view');
       
$this->load->view('common/admin_footer_view');
    }


Now all the work and logic is being done in your libraries. Your libraries call models to query the database to get the data, so your libraries can be slim too. You can unit test your libraries quite easily.

Not saying this is the only or best way but is what I would do and it does keep everything very easy to maintain whilst avoiding big fat controllers. So not 1 to 1, nor 1 to many, but 1 to 'some' related methods. So I would have edit_user and add_user in the users.php controller, but keep them very, very thin and do all the actual work in libraries and models.
I have to agree with @PaulD, keep your Controllers small and lean place all business logic into your Models.
Thanks for that PaulD. It's an option I'd been thinking about, but had got fixated on just the two opposite options. It was good of you to lay it out like that for me too. I can definitely see how it can be applied to the Manager section in my project.

And I agree with yourself and InsiteFX, the bulk of the processing code will be in models. Some of the batch data processing routines are pretty complex and definitely do not belong in the controller.
Thanks PaulD! I got it