views:

286

answers:

2

I'm trying to implement the Active Record pattern to a ZF project. I used to work with a similar approch before and it works well.

But my problem now, is about how to handle many-to-many relationship with my models.

Here is an example :

Let's say i've an User model.

<?php
require_once 'MLO/Model/Model.php';

class Model_User extends MLO_Model_Model
{   
    protected $_data = array(
        'id' => NULL,
        'email' => NULL,
        'password' => NULL,
    );
}

No problems.

But what if I add a Group model ?

require_once 'MLO/Model/Model.php';

class Model_Group extends MLO_Model_Model
{   
    protected $_data = array(
        'id' => NULL,
        'name' => NULL,
        'desc' => NULL,
    );
}

and

require_once 'MLO/Model/Collection.php';

class Model_Groups extends MLO_Model_Collection
{   
    protected $_modelClass = 'Model_Group';
}

I have then a mapper which convert results from the db to model object, and vice versa.

My question is, how to handle many-to-many relationship with my models ?

Where should i "store the relationship" ?

Here is some clues i think about :

class Model_User extends MLO_Model_Model
{   
    protected $_data = array(
        'id' => NULL,
        'name' => NULL,
        'desc' => NULL,
        'groups' => NULL,  // where groups will be an instance of the Model_Groups
    );
}

With the same approach, where groups will be an array like :

array(3) {
  [0]=>
  array(3) {
    ["id"]=>
    string(1) "9"
    ["name"]=>
    string(1) "Guest"
    ["desc"]=>
    string(1) "Some desc"
  }
  [1]=>
  array(3) {
    ["id"]=>
    string(1) "64"
    ["name"]=>
    string(1) "Moderator"
    ["desc"]=>
    string(1) "Some desc"
  }
  [2]=>
  array(3) {
    ["id"]=>
    string(1) "5"
    ["name"]=>
    string(1) "Admin"
    ["desc"]=>
    string(1) "Some desc"
  }
}

Another ideas ?

P.S : I'm not trying to handle ACLs or similar things, it's just for example.

A: 

Let's translate your problem to post tags - one post have many tags and one tag is used with many posts - it's easily understandable (at least to me):

I would add ['tags'] to Page's $_data as you suggest. And it will be array of adjected tag objects. Analogicaly for Tag I'd add ['pages'] with adjected pages. But I would use lazy loading for that of course.

Tomáš Fejfar
So you would assign to both Pages and Tags (or Users and Groups in my example) the respectives Tags and Pages ?, and pass the class Name in the array to lazy load the Tag/Page object ?What's wrong with the use of a collection object which contains the tag/page objects ?
Boris Guéry
OF course you can use Collection... :) It's quite the same - I'm just used to do it this way, sry... Problem is you can get to infinite loop (load Tags for Pages each Page object needs Tags, they are loaded and each tag has Pages, load Pages...) that's why lazy loading is needed. Also I would recommend using some sort of cache to store the result as it might get pretty database intensive :)
Tomáš Fejfar
+1  A: 

Zend_Db_Table has this functionality built in! :)

It uses its own concepts of "dependentTables" and "referenceMap" to manage table relationships and can even do CASCADE and DELETE stuff for you if your DB doesn't support referential constraints

Zend_Db_Table Relationships

Alex