views:

118

answers:

3

I'm writing my first application with Zendframework. My question is about the Model–View–Controller (MVC) architectural pattern.

I currently have a model with refer to a database table. Here's the classes that I currently have :

Model_Person 
Model_PersonMapper 
Model_DbTable_Person

Now, I see a lot of examples on the net, but all of them are simple cases of insert/update/delete. In my situation, I have to check if a person exists, and if it doesn't, I have to insert it and retrieve the ID (I know save return the Id, but it's not exactly what I have to do, this is and example).

It's quit simple, but I want to know where to put the database logic for all the others specific cases. Some others cases might involve checks across other tables or ... whatever !

Should I add all the specific functions in my Model_XXXXMapper with something that would be very specific with the current validation/process that I want to do? like a function getIdOfThePersonByNameOrInsertIfNotExists() (sample name of course!!!)

Or should it reside in the controller with some less specifics access to my model would be validated?

In other word, where do I put all the data specifics functions or check ?

+1  A: 

I would definitely split the function up into search/create functions.

Here's a basic implementation...

$personTG = new Model_PersonTableGateway;
if ( !$person = $personTG->findByName( $name ) ) {

    $person = new Model_Person;
    $person->name = $name;
    // other variables
    $newPersonId = $personTG->create( $person ); // creates a new person

}

I use table gateway. You can substitute your class for the TG.

You can have the create() function return just the id of the newly created person, or the entire person...it's up to you.

Galen
You would do that in the controller or any class that perform the action/check ?I thought that all the data or database logic had to reside in the model. but ok, thx.
Pmax
That would go in the controller. The controller prepares the info for the view using the models as data retrievers. That's all that code is doing.
Galen
+1  A: 

I think the real work should occur in your model objects, not in the controller. Any selects/creates that start with the person table would be in the DbTable_Person object, things like:

// DbTable_Person
// returns sets of or single Person objects
public function createByName( $name ) // perhaps throws exception if name already exists
public function findById( $id )
public function findByName( $name )
public function findHavingAccount( $account_id ) // references another table

// controller
// with your example, like what Galen said,
// I would let the controller handle this logic
$person = $person_table->findByName($name);
if ( !$person ) {
  $person = $person_table->createByName($name);
}
if ( !$person ) { throw new Zend_Exception('huh?'); }
$id = $person->id; // you wanted the ID
Derek Illchuk
I've read somewhere that it's up to me... it's only a question of preference finally.. A thin controller vs a fat controller.As you say, I rather to keep the logic of the database in the model. thx
Pmax
A: 

You might be interested in Zend_Validate_Db_NoRecordExists and its sister. If you are using Zend_Form you can add this validator to your form element. Many folks use Zend_Form to validate and filter data before they reach the domain model.

If you are not using Zend_Form, you can simply use this validation class in your service layer. A simple service class could be something like

 `
class Service_Person_Validate 
{ 
  public function creatable($data) 
  { // return true|false 
  } 
}
Sudheer