ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

DataMapper ORM v1.8.2

November 30, 2011 3:43pm

Subscribe [100]
  • #106 / Jan 08, 2012 2:04am

    Mark Price

    24 posts

    I am working with some many to many relationships and have my relationships defined as the following:

    class Users_model extends DataMapper
    {
        public $table = "users";
        public $has_many = array(
            'profile_fields' => array(
                'class' => 'profile_fields_model',
                'other_field' => 'users',
                'join_self_as' => 'user',
                'join_other_as' => 'profile_field',
                'join_table' => 'users_profile_fields',
            ),
        );
    }
    
    class Profile_fields_model extends DataMapper
    {
        public $table = "profile_fields";
    
        public $has_many = array(
            'users' => array(
                'class' => 'users_model',
                'other_field' => 'profile_fields',
                'join_self_as' => 'profile_field',
                'join_other_as' => 'user',
                'join_table' => 'users_profile_fields',
            ),
        );
    }

    When I execute the command

    $User->save($Profile_field);

    I get the error “Unable to relate users_model with profile_fields_model.”

    I started to dig a little deeper and realized that DatamMapper (line 5041 and 5492) is trying to look up the relationship by the model name “profile_fields_model” instead of looking at the other_field parameter “profile_fields”.

    I was able to get around this by using the following code:

    $User->save($Profile_field, 'profile_fields');

    But now I am stuck trying to find a work around using set_join_fields()

     

  • #107 / Jan 12, 2012 6:36pm

    Andrew S

    1 posts

    There appears to be a small bug in nestedsets extension method dump_dropdown().

    The check on $field making sure it exists will always fail. It’s checking if it exists in the fields property on the wrong object.

    The first line reads:

    public function dump_dropdown($object, $field = FALSE, $skip_root = TRUE)
     {
      // check if a specific field has been requested
      if ( empty($field) OR ! isset($this->fields[$field]) )

    When it should read:

    public function dump_dropdown($object, $field = FALSE, $skip_root = TRUE)
     {
      // check if a specific field has been requested
      if ( empty($field) OR ! in_array($field, $object->fields) )
  • #108 / Jan 12, 2012 6:54pm

    WanWizard

    4475 posts

    Absolutely right, good find!

    I’ve already changed it locally, I’ll push it to the repo as soon as I have proper internet access…

    Thanks for reporting it.

  • #109 / Jan 18, 2012 12:51pm

    Spir

    139 posts

    Hi,
    I’m here again with my many to many relationship noobs question.
    What is the best way to load join field when iterating on items.
    Here are the models :

    class Items extends DataMapper {
        public $has_many = array(
            'lang' => array(
                'class' => 'lang',
                'other_field' => 'item',
                'join_self_as' => 'item',
                'join_other_as' => 'lang', would be 'lang_id'
                'join_table' => 'items_langs'
     ),
        );
    }
    class Langs extends DataMapper {
        public $has_many = array(
            'item' => array(
                'class' => 'item',
                'other_field' => 'lang',
                'join_self_as' => 'lang',
                'join_other_as' => 'item', would be 'item_id'
                'join_table' => 'items_langs'
     ),
        );
    }


    Now I’m loading all items and looping on them. I want to display their data and the field “name” which is a data in the joined field (ie. in the table items_langs).

    I have loaded my current language and I want to display the name of the item in my language. What is the best way to do it?

    $items = new Item();
    $items->get();
    
    foreach($items as $item)
    {
        $item->lang->where('id', $default_language->id)->include_join_fields()->get();
        echo $item->lang->join_name;
        // Would be nice to pass related field as param like this :
        $item->include_join_fields($default_language)->get();
    
    }

    Lang is already loaded why loading it again? Any better solution?

    Ok some update. I did pause that project and now I’m back on it. There is one things that I made wrong with that code that keep me scratching my head for some time. Don’t use lang as a model name 😊
    and RTFM! 😛
    http://datamapper.wanwizard.eu/pages/reservednames.html

    The error I had was :
    Unable to call the method load

    Just in case someone stumble on this…

  • #110 / Jan 18, 2012 7:04pm

    Mark Price

    24 posts

    Is there a way to reference a specific record in the Datamapper query results?

    For example I have a Datamapper instance that has already queried and is storing all of the table records. Now I want to reference this Datamapper instance for a specific record by the record id without having to query the database again.

    Is this possible?

  • #111 / Jan 19, 2012 2:35am

    WanWizard

    4475 posts

    If you have “all_array_uses_ids” in your config set to TRUE, you can access the records in the resultset using

    $myrec = $model->all[$id_your_looking_for];

    you can access by id only though. In all other situations you’ll have to iterate over the object to find it.

  • #112 / Jan 19, 2012 11:36am

    Mark Price

    24 posts

    If you have “all_array_uses_ids” in your config set to TRUE, you can access the records in the resultset using

    $myrec = $model->all[$id_your_looking_for];

    you can access by id only though. In all other situations you’ll have to iterate over the object to find it.

    Thank you WanWizard, that is exactly what I was looking for.

  • #113 / Jan 23, 2012 3:51pm

    Max1234

    1 posts

    I ran into problems with this line of code:

    $object->where_in('id', $ids)->get();

    $ids is an array. When it has more than one element it works perfectly, but when it only has one element the query isnt executed. Is this behavior wanted?

     

  • #114 / Jan 23, 2012 4:56pm

    WanWizard

    4475 posts

    Datamapper uses CI’s where_in method (_where_in in DB_Active_Rec to be exact), and simply passes the table name, field name and array to it.

    I’ve looked at that code too, but I can’t see why it would fail on an array with one element.

    Tried this in my test environment (latest DM, CI 2.0.2), without problems:

    $table1 = new table1();
    $table1->where_in('id', array('1'))->get();
    var_dump($table1->all_to_array());

     

  • #115 / Jan 24, 2012 1:36am

    Mark Price

    24 posts

    I’m trying to figure out how I can query results using the relationship id of a record in the join table.

    The documentation gives an example similar to the one below:

    $alarm = new Alarm();
    $alarm->where_join_field('user', 'id', 1)->get();

    But this does not add the JOIN statement to the join table in the SQL query. Only the WHERE clause.

    Then I gave the following a try:

    $alarm = new Alarm();
    $alarm->include_related('user', 'id')
        ->where_join_field('user', 'id', 1)
        ->get();

    The problem with this is that include_related() aliases the table names and the new alias is not used in the WHERE clause causing column ‘id’ not to be found.

    Any ideas how I would go about this using the relationship id?

    Thank you

  • #116 / Jan 24, 2012 2:37am

    WanWizard

    4475 posts

    The idea behind where_join_field() is that it allows you to filter relations based on a join_field, so a non-key column in your relationship table. This only works if you’re actually querying a relation, and therefore the method only adds a WHERE clause, and assumes the JOIN is already there.

    If you want to query on a related object value, you would use

    $alarm = new Alarm();
    $alarm->where_related_user('id', '1')->get();

    DataMapper is smart enough to detect that this is a foreign key in the relationship table, and only join that table.

  • #117 / Jan 24, 2012 5:22pm

    Kyle Noland

    22 posts

    Is there a way to accomplish some kind of where_related_count type query on deep relationships?

    I have Categories, which have many Templates. Templates can have many Procedures. I want to return all the categories that have at least one related Procedure.

    This doesn’t work, but I’m trying to create a query along these lines:

    $categories = new Category();
    $categories->include_related_count('template/procedure')->get_iterated();
    foreach($categories as $category)
    {
        if($category->template_procedure_count > 0)
        {
            // Save this category for output later
        }
    }
  • #118 / Jan 24, 2012 6:18pm

    ivus

    1 posts

    Many-to-Many Reciprocal Self Relationships - not working?

    I’ve followed the steps outlined on this page http://datamapper.wanwizard.eu/pages/advancedrelations.html and maybe I’m missing something but I can’t seem to get it to work.

    Basically I want to create a comments page where the data is stored in 1 table. Any comments that have parent_id of zero is assumed to be the top level comment and all replies will have a parent_id of the top level comment.

    My model

    class Comment extends DataMapper {
    
     var $has_many = array(
      
      'relatedcomment' => array(
       'class' => 'comment',
       'other_field' => 'comment'
      ),
      'comment' => array(
       'other_field' => 'relatedcomment',
       'join_other_as' => 'parent'
      )
      
     );
    }

    My join table

    CREATE TABLE IF NOT EXISTS `join_comments_comments` (
      `id` bigint(20) NOT NULL auto_increment,
      `comment_id` bigint(20) NOT NULL,
      `relatedcomment_id` bigint(20) NOT NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;

    My controller

    function wall($id)
     {
      $course = new Course($id);
      $course->comment->get();
     }

    When I try to execute the code, I get a blank page, as if the page is stuck in an endless loop.

    Any help would be great. Thanks.

  • #119 / Jan 24, 2012 6:29pm

    WanWizard

    4475 posts

    I think you can, but you’ll have to use a subquery which is going to make it complex.

    It would be handy if DataMapper would support WHERE EXIST, but it doesn’t (and I’m not sure all RDBMS’s support that, so many not a good idea either).

    Alternatively, you could add a custom method to your model, write a standard query for it, run that using $this->db->query, make sure it returns at least the category id column, and convert the result back into the object by calling

    $result = $this->db->query('your sql here');
    $result and $this->_process_query($result);
  • #120 / Jan 25, 2012 11:53am

    diZzyCoDeR

    25 posts

    Guys, I have this problem that’s beyond my level of understanding.  So I will attempt to explain and then see if there’s an obvious solution.

    I have tables in a separate DB Server - MSSQL (ya, ya, I know) with ‘ID’ (BIGINT)
    My server is a 32-Bit Windows 2008 server w/ PHP 5.3.8
    The ‘id’s in one of my tables get above 2147483647 .. and when the do, they simply get returned as 2147483647 (the MAX_INT_VAL of my 32-bit PHP installation)

    From what I understand, PHP is supposed to automatically cast to FLOAT when an integer value gets larger than it’s supported maximum.

    What I was thinking of doing, because I use a lot SQL VIEWS, is just modifying the SQL view for my table with this:

    SELECT CAST(ID AS varchar(50)) AS id

    UNLESS, that is, there is something else that is more proper (other than moving to a 64bit platform.. lol) like forcing the ID’s to (float) in my model somehow.

    *confuzed*

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases