views:

378

answers:

4

Hi all,

EDIT:

What is the best way to structure complex applications with CodeIgniter? To make this question more specific, maybe to just focus on structuring controllers: If you have a Users controller, than should all functions be in this one file? In other words, you might have controller actions that tie to specific views, but a bunch of helper functions as well.

ORIGINAL QUESTION: Given a complex application, with Users, Transactions, Products, does it make sense to have a Controller for each of them? And since each of these corresponds to a database table, to have a corresponding model for each of them? I think it does, but an application I am currently working on consists of one 3000 line controller and one 3000 line model. Just want to verify the standard practice regarding CI and the application structure.

A: 

should separate controller. but controller also change the url if you do not use router to alter it.

for Model, i usually map 1 controller to 1 model, if DB cost more than 4 lines.

joetsuihk
A: 

First of all, model definately needs seperating to something like:

user_model:
 add_user();
 delete_user();
 ...

products:
 add_product();
 delete_product();
 ...

transaction:
 ...
 ...

you should get the idea.

Controller could do with some seperation as well. My controllers in this scenario would be.

products:
 add_product();
 show_product();
 get_product();
 ...

users: 
 add_user();
 delete_user();
 ...

and so on. The reason for repeating same functions in controllers and models is that you can easily change model to access different database/data source and nothing beyond that needs changing.

Besides, there's absolutely no need to load product model when you're adding user for example.

LukeP
in my point of view, class products' method do not need "_product", as $product->add() is enough, $product->add_product() is repeating yourself.
joetsuihk
I started the '_product' convention a long time ago on a project, and I'd give anything to go back. It ends up being sooo much extra typing.
Zack
Both of you are absolutely right.
LukeP
+2  A: 

I'd like to share my application structure here.

I start with model. I write 1 model for one table in the mysql database. I already have MY_Model class that I put in system/application/libraries/ folder. This class have get_detail, get_list, get_total, get_all, insert, update, and delete method. I store the table name in a var, so basically I just need this code in model to make it worked:

class Some_table_model extends MY_Model {
  function Some_table_model()
  {
    $this->tablename = 'some_table';
    $this->primary_key = 'id';
  }

}

Update: after some more project, I have added new var to hold the column name used for primary key in the table. This way, I will have more flexibility by not hard coded the column name for primary key in MY_Model.

For the controller, I create it according to it's usage by user. Example for a product, I will have this controller:

function Product extends Controller {
  function index()
  {
    //display product list, paginated
  }
  function admin()
  {
    //protected by session
    //display product list for admin, paginated
    //handle POST request to delete a product or products
  }
  function form()
  {
    //protected by session
    //handle add/edit product for admin
  }
}

View is related to controller. For above controller, I will have at least 3 view file:

product_list.php
product_admin.php
product_form.php

View can be placed in subdir, for example, I can arrange it like this:

system/application/views/front/product.php
system/application/views/admin/product_list.php
system/application/views/admin/product_form.php

If product have category, I will need another table and model for it, but for controller, I can put the page inside Product controllers, by adding category into the function name:

function category_admin()
{
  //get parameter
  //...
  //process data
  //...
  //redirect or load view
  //...
}

function category_form()
{
  //get parameter
  //...
  //process data
  //...
  //redirect or load view
  //...
}

That's what I do and it's work for me. Hope this help you find a better way to refactor your CodeIgniter's code.

Donny Kurnia
Does this assume that all of your primary keys are 'id'?
m_oLogin
Recently I have update MY_Model by adding new property: $primary_key. This property will hold the table's primary key column name, default is 'id'. This way, I can have flexibility to work with table that use columns other than 'id' as primary key, example: 'country_id'.
Donny Kurnia
Most of this is a good idea but I generally avoid mixing Admin code and frontend code. While most of the data interaction will be the same or similar, you have to remember that the more code in your controllers the slower they will be. There is no need for PHP to parse all that unrelated admin code for each frontend user to look at your site.
Phil Sturgeon
Yeah Phil, that's why I always try to kept the Controller's small. In my latest project, my client want a really custom url, so all front pages is handled by 1 special controller. The more code you write, more fine it become. I even feel shame with the code I wrote 6 month ago :)
Donny Kurnia
A: 

If you're really concerned about project organization, you should check out Matchbox.

From the Matchbox Docs:

Matchbox is a set of extended libraries that lets you organize your application in small components (modules). These modules have several advantages, the main one being portability. Modules are stored in their own folders and so they can be reused in other applications or shared between users by copying just that one folder.

This allows you to really organize your content by placing related models and controllers in the same folder.

Zack