Welcome Guest, Not a member yet? Register   Sign In
What goes where? (MVC)
#11

[eluser]SomeFunkyDude[/eluser]
OK, so a Controller can also load the libraries/plug-ins/helpers etc which ARE NOT models, but I can create my own libraries that add functionality, but if the classes that I create contain some sort of database interactivity, I should probably save it as a Model.

Rich: Thanks for clarifying your example.
#12

[eluser]dsloan[/eluser]
In the past I've been confused about how "libraries", "helpers" and other "classes" fit into the MVC architecture, especially within CI and the $this->load->model('myModel') approach, but eventually got it sussed in a way that makes perfect sense for us.

The view doesn't need any explanation since it's not where the confusion usually lies, so I'll concentrate on how we interact between the Controller and Model tiers, and give some simple examples relating to a property/landlord theme from one of our products. For info, a landlord may own multiple properties. This example is very simplistic, but should demonstrate how you can use a model in conjunction with regular classes to model business logic.

The controller is very thin, with each method consisting of typically 20 lines or less, and it just directs the request to the appropriate method with the model, and then passes the resultant data back to the view. It has absolutely no business logic involved.

Consider the action of adding a property, much simplified for example.

Controller:
Basically all it's saying is "ok, so you want to add a property, ok, propertyModel, go add the property, you'll know what to do."

Code:
class Property extends Controller {
    public function add() {
        $data = $_POST;
        // Yes, I know this needs sanitised, just shortened version
        $this->load->model('propertyModel');
        $this->propertyModel->add($data);
    }
}

Model:
The model itself (models/propertyModel.php) contains the business logic, or high-level list of operations needed to add a property to the database. However, and this is the bit that took me a while to get to grips with, in order to implement the business logic it needs to use classes, libraries, etc. These can now be used in traditional OO style.

The model can be viewed as a storyboard of what is involved in the whole operation, with the actual actions being performed by the relevant classes, interacting as required.

Before I go any further, we store all our application classes in the libraries folder, in subfolders to help classify them. We also name them according to the folder structure to avoid name clashes, and adopting the same approach as e.g. Zend Framework. Indeed we have dropped the Zend Framework into libraries/Zend and can use these classes in the same way as any other.

For example, our application is called Rentpro, so we have application-specific classes in a Rentpro subfolder. We call the Property class Rentpro_Property and it is stored in libraries/Rentpro/Property.php. See, the name reflects the path, and avoids name clashes, in the same way as e.g. Zend_Config_Exception is located in Zend/Config/Exception.php

Code:
class PropertyModel extends Model {
    public function add($data) {
        $myProperty = new Rentpro_Property();
        $myProperty->add($data);

        $myLandlord = new Rentpro_Landlord($landlordId);
        $myLandlord->addProperty($myProperty);
    }
}

Libraries:
The custom application "classes" or "libraries" are then defined in the libaries folder as explained above, and allow you to focus on them in proper OO style.

We take things a step further by abstracting the actual data access to Data Access Models, once for each database table. These are generated automatically from the database schema, but that's another topic. For completeness though, these Data Access Models are stored in the application/models/dao folder.

Code:
class Rentpro_Property () {
    public function add($data) {
        $propertyDO = new DAO_Property();
        $propertyDO->setFrom($data);
        $propertyDO->insert();
    }

    public function transfer(RentPro_Landlord $landlord) {
        ...
    }

    public function generateReport($startDate, $endDate) {
        ...
    }
}

Some may view the data abstraction as an extra level of complexity, but it keeps the actual class completely independent of the underlying database, and this is worth the slight performance overhead for ease of maintenance. It also allows you to continue to write your application at a reasonably high "business-logic" level. I don't advocate writing raw SQL within your classes.

View:
We use Smarty as the template engine for the view.

This works well for us, but I'd be interested to hear other people's opinions.

Diarmid




Theme © iAndrew 2016 - Forum software by © MyBB