"Skinny Controller, Fat Model" approach in symfony project

September 10th, 2007
A very common error when you first start to write an application in the MVC way is bypassing some of the components or just not using it as it should.
This problem and an example how to do it in the "right way" are described in a one of Jamis Buck's posts called Skinny Controller, Fat Model.

Here is a cover-up version of the code from that post ported to symfony/PHP...

Before (or how-NOT-to-do-it example) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- listSuccess.php -->
<?php
  foreach ($path as $breadcrumb=>$name)
  {
    ?>
      <a href="<?=url_for($breadcrumb)?>"><?=__($name)?></a> / 
    <?
  }
  
  foreach ($people as $p)
  {
    ?>
      <div id="person-<?=$p->getId()?>">
        <span class="name">
          <?=$p->getLastName()?>, <?=$p->getFirstName()?>
        </span>
        <span class="age">
          <?= (date('Y') - date('Y', strtotime($p->getBirthdate()))) ?>
        </span>
      </div>
    <?
  }
?>
1
2
3
4
5
6
7
8
9
10
11
12
# actions.php
class personsActions extends sfActions
{
  public function executeList()
  {
    $c = new Criteria;
    $c->add(PersonPeer::ADDED_AT, date('Y-m-d'), Criteria::GREATER_EQUAL);
    $c->add(PersonPeer::DELETED, false);
    
    $this->people = Person::doSelect($c);
  }
}
1
2
3
4
# PersonPeer.php
class PersonPeer extends BasePersonPeer
{
}
After (or do-it-in-this-way example) :
1
2
3
4
5
6
7
8
9
<!-- listSuccess.php -->
<?php echo breadcrumbs($path) ?>

<?php foreach ($people as $p): ?>
  <div id="person-<?php echo $p->getId()?>">
    <span class="name"><?php echo $p->getFullName()?></span>
    <span class="age"><?php echo $p->getAge()?></span>
  </div>
<? endforeach;?>
1
2
3
4
5
6
7
8
# actions.php
class personsActions extends sfActions
{
  public function executeList()
  {
    $this->people = PersonPeer::findRecent();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# PersonPeer.php
class PersonPeer extends BasePersonPeer
{
  public function findRecent()
  {
    $c = new Criteria;
    $c->add(self::ADDED_AT, date('Y-m-d'), Criteria::GREATER_EQUAL);
    $c->add(self::DELETED, false);

    return self::doSelect($c);
  }
}

# Person.php
class Person extends BasePerson
{
  public function getFullName()
  {
    return $this->getLastName() . ', ' . $p->getFirstName();
  }

  public function getAge()
  {
    return (date('Y') - date('Y', strtotime($this->getBirthdate())));
  }
}



3 Responses to “"Skinny Controller, Fat Model" approach in symfony project”

  1. Klemens Says:
    Thanks for this "translation" into symfony php code!
  2. Raphael Says:
    How would you extend that to using something like sfPropelPager? Would you move the pager initialization into your model as well? or perhaps just set the pager function to call the relevant method (like for example your findPerson method)?
  3. Krasio Says:
    Previously I used to init the pager in th action, but now I'm using sfPropelFinder plugin, it has it's own paginate() method so this also goes in the model. You can find more info for sfPropelFInder here - http://redotheweb.com/2008/07/02/sfpropelfinder-now-with-i18n-pagination-and-update-queries/

Leave a Reply