Understanding MVC: Whats the concept of "Fat" on models, "Skinny" on controllers?

punkbit picture punkbit · Jun 24, 2010 · Viewed 8.6k times · Source

I'm trying to understand the concept of "Fat" on models vs "skinny" on controllers and from what I've been discussing I have the following example (this is taken from a freenode discussion):

Q: On MVC paradigm, its said Fat models, skinny controllers. I'm here thinking, If I have lots of methods (on controller) that uses just a few abstract methods to CRUD (on model), am I creating a fat controller instead of a model ? Or they say, fat model, refearing in what is returned and not typed ? that's something I've never understood =) Any comments are appreciated! Thanks a lot

OBS1: I'm not doing whats ment by the model, in the controller, I just have methods that control whats going to the model

OBS2: let's say "checkIfEmailExists()", has "[email protected]", as a parameters. This method will, get the return from the model method that querys if this param exist in table, return boolean. If is 0, "checkIFemailExists()" will call a diferent model method, this one, he's just another abstract method, that performs Update operation.

OBS3: The "checkIfEmailExists()", isnt just a controller ? He's not actually performing any CRUD, he's just comparing values etc. That's whats confusing me, because in my head this is a controller :S

Notes: I guess this is not the best example, since saying "check if something exists",sounds like a query my table operation

Q2:just one more question, so, let's say I've got a view form, from where that email address parameter is sent from. Are you saying the view goes directly to the model ?

Q3:Shouldn't the controller act between them ? thats the paradigm

FINAL NOTE: The discussion ended, saying that I'm wrong, wish is ok (i'm learning). But, so, whats the right answers for Q2 and Q3 ?

Thanks for your atention

Answer

Gordon picture Gordon · Jun 24, 2010

Your application is the M. It should be able to stand independent from V and C. V and C form the User Interface to your application. Whether this is a web interface or a command line interface shouldn't matter for the core business logic of your application to run. You want the model to be fat with business logic.

If you have a fat controller instead, e.g. full with business logic, you are not adhering to the purpose of MVC. A controller's sole responsibility is handling and delegating UI requests to the Model. That's why it should be skinny. It should only contain code necessary for what it's responsible for.

Simplified Example

public function fooAction()
{
    if(isset($_POST['bar'])) {
        $bar = Sanitizer::sanitize($_POST['bar']);
        $rows = $this->database->query('SELECT * from table');
        try {
            foreach($rows as $row) {
                $row->foo = $bar;
                $row->save();
            }
        } catch (Exception $e) {
            $this->render('errorPage');
            exit;
        }
        $this->render('successPage');
    } else {
        $this->render('fooPage');
    }
}

When it should be

public function fooAction()
{
    if(isset($_POST['bar'])) {
        $success = $this->tableGateway->updateFoo($_GET['bar']);
        $page    = $success ? 'successPage' : 'errorPage';
        $this->render($page);
    } else {
        $this->render('fooPage');
    }
}

because that's all the controller needs to know. It should not update the rows. It should just tell the model that someone requested this change. Updating is the responsibility of the class managing the rows. Also, the controller does not necessarily have to sanitize the value.

As for Q2 and Q3, please see my answer to Can I call a Model from the View.