Question

I am building a small core piece for my DataMapper ORM library in CodeIgniter to control user's access/edit rights (CRUD) over DataMapper objects itself. For this I want to link a DataMapper Entity, Userrole and Userright together.

The documentation is here http://datamapper.wanwizard.eu/pages/advancedrelations.html (Under head; Multi-table Relationships).

So if I fill in the join table by hand I can just get the values without any problems. The only problem is saving the relationship.

Here are my Model-rules

Userrole

var $has_many = array(
    'userright' => array(
        'join_table' => 'dm_entities_userrights_userroles',
    ),
    'dm_entity' => array(
        'join_table' => 'dm_entities_userrights_userroles',
    ),
);

Userright

var $has_many = array(
    'dm_entity' => array(
        'join_table' => 'dm_entities_userrights_userroles',
    ),
    'userrole' => array(
        'join_table' => 'dm_entities_userrights_userroles',
    ),
);

Dm_entity

var $has_many = array(
    'userrole' => array(
        'join_table' => 'dm_entities_userrights_userroles',
    ),
    'userright' => array(
        'join_table' => 'dm_entities_userrights_userroles',
    ),
);

It seems odd I declared the table twice constantly, but it seems not to work if I don't.

So here's my retrieval code for this relation form the perspective of the Userright;

$userrole = new Userrole;
$userrole->get_where(array('name' => 'Administrator'));

$dm_entity = new Dm_entity;
$dm_entity->get_where(array('name' => 'User'));     

$userrights = new Userright;
$userrights->where_related($userrole);
$userrights->where_related($dm_entity)->get();

$output = '';

foreach ($userrights as $userright) {
    $output .= '<i><b>'.$userright->name.'</b></i> and ';
}

$output = substr($output, 0, -5);

echo '<b>'.$userrole->name.'</b> has the right to '.$output.' the DataMapper entity <b>'.$dm_entity->name.'</b>.'.br();

So this works without any problems either. But now the saving part:

$new_userright = new Userright;
$new_userright->get_where(array('name' => 'Update'));

$new_userright->save(array($userrole, $dm_entity));

Which results in two entries in the dm_entities_userrights_userroles table where 1 entry has dm_entity_id empty and the other the userrole_id empty.

I hope to avoid making a separate Model for the join table to solve this.

Does anyone know how I can get this to work so it makes one correct entry, instead of two scattered ones?

Was it helpful?

Solution

This is not going to work (as you have noticed).

A relation is between two models, and for each Many to Many relation you need a separate join table.

Although technically you can create a join table with 10 FK's to 10 different models, Datamapper will not be aware of that, and will treat the table as different for every relation, causing duplicates to appear.

The only way to make this work, is to define a model for the join table too, and give that one-to-many relations to each of the other models. You can then use that model to manually add relations by assigning or updating the FK values, and still use the many-to-many relations for retrieval and update.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top