Fork me on GitHub

some doctrine stuff  Bottom

  • So im struggling to learn doctrine, so instead of pestering a couple people for help all the time i thought id post it in the community and see if i can get help here, and if i can then this thread could be helpful to others in the future.

    so the module im working on is an instant messaging module (it was working well before re-doing it with doctrine)

    so for my Doctrine Records i have
    Users
    messages

    a user has many messages as sent messages
    a user also has many messages as recd messages

    id like it such that if a user sends a message to another user, the sender has that message as a sent message and the recvr has it as a recd message. id just like people to point out all my mistakes and discuss/debate the best way to accomplishing my goals.


    kyle

    here are my models

    Code

    class Zim_Model_User extends Doctrine_Record
    {
        /**
         * Set table definition.
         *
         * @return void
         */

        public function setTableDefinition()
        {
            $this->setTableName('zim_users');
            $this->hasColumn('uid', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => true,
                 'autoincrement' => true,
            ));
            $this->hasColumn('status', 'integer',  null, array(
               'notnull' => true,
               'default' => 0,
            ));
            $this->hasColumn('uname', 'string', 100, array(
               'notnull' => true,
               'default' => '',
            ));
        }

        /**
         * Record setup.
         *
         * @return void
         */

        public function setUp()
        {
            $this->actAs('Timestampable');
            $this->hasMany('Zim_Model_Message as SentMessages', array(
                'local'     =>  'msg_to',
                'foreign'   =>  'msg_from',
                'refClass'  =>   'Zim_Model_UserMessage'
            )
            );
            $this->hasMany('Zim_Model_Message as RecdMessages', array(
                'local'     =>  'msg_from',
                'foreign'   =>  'msg_to',
                'refClass'  =>  'Zim_Model_UserMessage'
            )
            );
        }





    Code

    <?php
    class Zim_Model_Message extends Doctrine_Record
    {
        public function setTableDefinition()
        {
            $this->setTableName('zim_message');
            $this->hasColumn('mid', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => true,
                 'autoincrement' => true,
            ));
            $this->hasColumn('msg_to', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => false,
                 'autoincrement' => false
            ));
             $this->hasColumn('msg_from', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => false,
                 'autoincrement' => false,
            ));
            $this->hasColumn('message', 'clob', array(
                'unique' => false,
                'primary'=> false,
                'notnull' => true,
                'default' => ''
            ));
            $this->hasColumn('recd', 'integer',2 , array(
            'unique' => false,
            'primary'=> false,
            'notnull' => true,
            'default' => 0
            ));
        }

        public function setUp()
        {
            $this->actAs('Timestampable');
            $this->hasOne('Zim_Model_User as to', array(
                    'local'     => 'msg_to',
                    'foreign'   => 'msg_from',
                    'refClass'  => 'Zim_Model_UserMessage'
            )
            );
            $this->hasOne('Zim_Model_User as from', array(
                    'local'   => 'msg_from',
                    'foreign' => 'msg_to',
                    'refClass'=> 'Zim_Model_UserMessage'
            )
            );
        }
    }


    Code

    class Zim_Model_UserMessage extends Doctrine_Record
    {
        public function setTableDefinition()
        {
            $this->hasColumn('msg_to', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => true,
                 ));
                 
            $this->hasColumn('msg_from', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => true,
                 ));
        }
    }
  • You have two primary fields. Primary = true must only exist on one field per record.

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • i was just using examples in doctrines docs to try to work from

    http://www.doctrine-project.org/projects/orm/1.2/docs/manual/defining-models/en#relationships:join-table-associations:many-to-many

    that shows multiple primary keys,

    Code

    class UserGroup extends Doctrine_Record
    {
        public function setTableDefinition()
        {
            $this->hasColumn('user_id', 'integer', null, array(
                    'primary' => true
                )
            );

            $this->hasColumn('group_id', 'integer', null, array(
                    'primary' => true
                )
            );
        }
    }
  • Could be an error in the docs, there are several issues in the documentation I found over time. The better way for you to see is create the table structure manually and dump it using the doctrine table schema dump tool. This is the recommended way anyhow.

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • the more i look at it the less sense what i have there makes to me anyway

    the model

    Code

    class Zim_Model_UserMessage extends Doctrine_Record
    {
        public function setTableDefinition()
        {
            $this->hasColumn('msg_to', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => true,
                 ));
                 
            $this->hasColumn('msg_from', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => true,
                 ));
        }
    }


    is supposed to map many-to-many associations between messages and users.

    for example theres a message, it has both a sender and a receiver, but there are many messages as well....

    i think it should be more like:

    Code

    class Zim_Model_UserMessage extends Doctrine_Record
    {
        public function setTableDefinition()
        {
            $this->hasColumn('uid', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => true,
                 ));
                 
            $this->hasColumn('mid', 'integer', 4, array(
                 'type' => 'integer',
                 'length' => 4,
                 'fixed' => false,
                 'unsigned' => false,
                 'primary' => true,
                 ));
        }
    }


    so that it actually associates a message (as identified by mid) to a user (as identified by uid)

    the other models would have to updated as well



    Another point of interest.
    one column cant be primary because that would also make it unique right? well there are many messages to/from many users so neither uid nor mid will be unique in this table. but the combination of mid and uid is unique
  • If you need unique columns, you should set a unique index on those fields like this:

    Code

    $this->index('myindex', array(
                    'fields' => array(
                        'eventname' => array(
                            'sorting' => 'ASC',
                            'length'  => 60),
                        ),
                    'type' => 'unique'));


    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • brainfart. yes i get that.

    I'm obviously kinda lost on this as ive never used anything like this... i find the documentation kindof lacking too

    any suggestions on how to make this model work the way i want it to ? even if i make it in the database first im not sure how id want to structure it to get the desired effects

    the basic concept of what im trying to do is:
    there are many users
    there area many messages

    a user has many messages that they have sent
    a different user will have those same messages that they have recd.

    so lets say user1 sends msg1 to user2

    user1 is associated with sending msg1
    user2 is associated with receiving msg1


    some thoughts on the overall structure of that would be appreciated.



    Edited by kylegio on Apr 26, 2011 - 01:22 PM.
  • Quote

    The better way for you to see is create the table structure manually and dump it using the doctrine table schema dump tool.

    where is this?
  • http://www.doctrine-…:existing-databases

    Code

    // make a dir for the 'my_models' to be stored
    // set connection
    $conn = Doctrine_Manager::connection('mysql://root:mys3cr3et@localhost/doctrine_test', 'doctrine');

    // dump the schema.
    Doctrine_Core::generateModelsFromDb('my_models', array('doctrine'), array('generateTableClasses' => true));


    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • Kyle,

    I cant stress enough. The best thing for you to do is create the table structure manually, then dump them into classes using the method above. Then you can add the relational stuff to the working models. It's the best way to learn so you aren't messing around with syntax.

    Regards,

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • i will do that .thanks for linking to the method of doing it, i was having difficulty finding it.

    I think one of the issues i am having though is the basic design of the tables themselves. I will play with it and see what i can come up with. I need my giant whiteboard back, i found it tremendously helpful when trying to visualize these things in my head.


    thanks for the help, i think it would be helpful for some module developers who are already using doctrine in their modules to post up some of their stuff/suggestions or links to it so that others have something to go with.


    Thanks
    kyle =)
  • Hey kyle
    I'm not sure if you need more than one table for this case. IMO to have your own Users table is a little headache considering that you have the core table already, and to sync your Zim table and the core one... well, I don't know.

    I guess you can get "a copy" of the Core Model with a method of DBUtil that I don't remember pretty weel right now, but that let you query your messages table with Joins if needed, but what I see briefly, is that Queries with UIDs+Time conditions are enough here.

    You could see some autogenerated code from Clip too (I will implement some stuff the next few days to see it) and a more complex study case could help you to use Doctrine on its full potential.

    Greetings

    --
    - Mateo T. -
    Mis principios... son mis fines
  • Hey Mateo,

    thanks for the reply.

    the users table only exist because it stores information like users status (online/away/etc), username (which is changeable)... the uid (userid) is not an auto-incrementing value, its actually populated from the zikula users table on first use, as is the username and stuff...

    but as this is a chat module the zikula users table just wont allow me to store the information i am/plan to store in it. so when a user first initializes the module they are created in the users table using the info from the core, but then from there the only thing that has to stay the same is their uid, theres no real link to core information like username and stuff. it also stores if they are online or not by using the updated_at field, this gets set every time the JS side of the code communicates with the zikula side, to ensure that if a user closes the window they don't ghost... zikula doesn't have anything suitable for that. thats why theres its own users table.

    The last push i made to it was in a working condition using doctrine i just dont feel it was using doctrine to its fullest extent. I think the current version on git is working for the most part.

    https://github.com/kylegio/Zikula-Instant-Messenger-

    if you want to check it out all you have to do is install the module, then add the chat block, i warn that its still very rough.

This list is based on users active over the last 60 minutes.