DataMapper ORM for Codeigniter Relations DataMapper ORM for Codeigniter Relations codeigniter codeigniter

DataMapper ORM for Codeigniter Relations


You are missing a couple key points to using the DataMapper for CodeIgniter. First off you need to do some pretty simple and important things. DataMapper (DM) uses normalized db naming to find relationships. What this means is if you query your db. Now it's a little harder to use DM for two columns and I think that you really don't need it.

First if you don't use DM you really only need two queries

SELECT u.*, m.* FROM messages AS m, users AS u WHERE m.from = u.id AND m.id = SOME_ID.

This query will get you all user details and message details for some message ID.Now this is semi-simple case because I am assuming a message can only be from one user.

For the to field on the other hand I will assume you should use a relational table. To use DM for it you have to name the table something like users_messages but again why do you need to use DM when it really is overkill.

Now for the from field you have a many to many relation because a message can have many users that it was to and a user can have many messages that they sent.

So create a table like this

CREATE TABLE message_to (    user_id BIGINT UNSIGNED NOT NULL,    message_to_id BIGING UNSIGNED NOT NULL,    PRIMARY KEY (user_id, message_to_id),);

If you want to do it right you will also use foreign keys but that depends on your DB

Now you can query really easily and get all the users a message was sent to.

SELECT u.*, m.* FROM users AS u, m AS messages JOIN messages_to AS m_t ON (u.id = m_t.user_id)

And querying the other way around is just as easy, getting all the messages a user has sent.

Remember just because a tool like DM exists doesn't mean it is the best tool for the job and actually using DM in this case incurs a pretty decent overhead when it is not necessary.

Doing this with DM would require the same things you just cannot name your tables/columns as you see fit and you need a class for every table creating it's relationship with other tables.

Meaning you have a lot of extra work to use DM, and you need to learn their syntax.


What you're looking for is a self-relationship.

If this is a 'has_one' relation, you can do that with in-table foreign keys. You do have to follow the naming convention for keys (to_id and from_id instead of to and from).

Currently (v1.8.0) you can only have one relation between any two models:

$has_one = array(    'to' => array(        'class' => 'messages',        'other_field' => 'messages'    ),    'messages' => array(        'other_field' => 'to'    ));

}

See http://datamapper.wanwizard.eu/pages/advancedrelations.html for more information.


  1. You have to make your models [models/users.php] and [models/messages.php] like this:

    class User extends DataMapper {    var $has_many = array(        'sent_message' => array(            'class' => 'Message',            'other_field' => 'sender',        ),        'received_message' => array(            'class' => 'Message',            'other_field' => 'receiver',        ),    );}

class Message extends Datamapper {var $has_one = array(    'sender' => array(    'class' => 'User',    'other_field' => 'sent_message',    ),    'receiver' => array(        'class' => 'User',        'other_field' => 'received_message'),);}

I Only have proviede $has_one and $has_many and you have to include the rest of models.


  1. you have to deifne your tables like this:

Table Name: users fields: id, email, ....

Table Name: messages [this is the important table in this case] field: id, sender_id, receiver_id, subject, message, created, ....


Now have to fill your database with example messages and then you can test like this:

for example User X is logged in and is now an object. You get users last 10 Messages like this:

    $messages = new Message();$messages->where_related_user('id', $user->id);$messages->limit(10);$messages->get();

you can get the reciever and sender of each message like this:

$messages = new Message();$messages->include_related('sender');$messages->include_related('receiver');$messages->get();

Now print the name of each sender and receiver:

foreach($messages as $message):echo $message->sender->name;echo $message->receiver->name;endforeach;