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 1.6.0

September 05, 2008 12:32pm

Subscribe [115]
  • #796 / Apr 25, 2009 11:00pm

    NachoF

    171 posts

    Ok, I have run into a big problem… Im sorry to ask for help again but Im very stuck…
    I am using DMZ cause I didnt want to create new tables for each relation.
    I have Event, Type, Client
    Event has one Type and one Client
    Type has many Events
    Client has many Events
    ...
    my events table has id, client_id and type_id… after a form I call this method… which always throws me an error that says I should call set method when updating… but Im creating a bran new Event…

    function send_event()
            {
            $e = new Event();
            $c = new Client();
            $t = new Type();
            $c->where('id','1')->get();
            $t->where('id','1')->get();
            $e->save(array($t,$c));             
            }

    Just in case you are wondering, those queries do produce wanted results.. its just the “$e->save(array($t,$c));” that appears to fail for me… my form is done through ajax but I doubt that has anything to do with it .

    Also, my tables are InnoDB and have foreign keys.

  • #797 / Apr 26, 2009 1:19am

    OverZealous

    1030 posts

    @NachoF
    I believe the issue is you are not setting any fields on Event.

    DataMapper needs to have at least one field set to save.  If you have an object that is using all default values, you’ll have to either set one of those values, OR (as I have done), create a special column just to set a value for the purpose of saving.  It could be a one-character, fixed-width column.

    Note: This is not in the docs.  I found this out the hard way, myself.

    @qureshi
    I’m glad you got it working.  Just so you know, if you already have $verse looked up, you can save a little bit of work typing, and loading in classes, by using this format:

    $user->link->where_related($verse->id);

    DataMapper can then use the table information from $verse, instead of creating a new object!

    I wish I could help you with info on donating, but stensi has disappeared since February :blank: .

  • #798 / Apr 26, 2009 9:56am

    NachoF

    171 posts

    @NachoF
    I believe the issue is you are not setting any fields on Event.

    DataMapper needs to have at least one field set to save.  If you have an object that is using all default values, you’ll have to either set one of those values, OR (as I have done), create a special column just to set a value for the purpose of saving.  It could be a one-character, fixed-width column.

    Note: This is not in the docs.  I found this out the hard way, myself.

    Wow, you are good, I was never gonna figure that one out… there seems to be a problem still though… I have noticed that the way datamapper is set up is that it first creates the row with the data provided and then updates the row with the ids of the related fields… the thing is, if you have InnoDB relations set up mysql wont allow the creation of the row if the client_id and type_id arent provided in the same insert query (is there any config I can change to force that behaviour?).... Im using phpmyadmin with InnoDB tables to set up the relations….  heres an image that will help you understand what I mean by InnoDb relations…
    http://img19.imageshack.us/img19/5315/relation.jpg
    Do you think I should start using those “internal relations” instead of innoDb relations… I do it this way to protect my database?

  • #799 / Apr 26, 2009 10:32am

    qureshi

    14 posts

    Hi OverZealous,

    Thanks for the tip. I’ll be sure to try it out.

    Sorry to hear that Stensi has disappeared. I hope he/she is safe and well.

    I ran this code a few minutes ago within my “main” controller:

    //Temp: relate translations to categories
        function relate(){
                         
                         //Get all categories
                         $categories = new Category();
                         $categories->get();
                         
                         //loop
                         foreach ($categories->all as $category):
                                          
                                         //Get verses
                                         $category->verse->get();
                                         
                                         //loop
                                         foreach ($category->verse->all as $verse):
                                                          
                                                         //Get translations
                                                         $verse->translation->get();
                                                         
                                                         //loop
                                                         foreach ($verse->translation->all as $translation):
                                                         
                                                         //relate translation and category
                                                         $translation->save($category);
                                                         
                                                         //clear the object data
                                                         unset($translation);
                                                         
                                                         endforeach;
                                                         
                                                         //clear verse
                                                         unset($verse);
                                                         
                                         endforeach;
                                         
                                         //clear category
                                         unset($category);
                                                                         
                         endforeach;
                         
                         }

    However, as I saw it go on, it used up almost 400MB of memory. Is this normal, or is my code poorly written? i’ve also tried using the $object->clear() function instead of unset(), but no noticeable difference. I also noticed trough observing the table in phpMyAdmin that rows inserted per second drops from 2000 in the very beginning to 30 towards the end. Would you know why?

    If it matters, I’m using an I7 920, 6GB DDR3 at 1600MHZ and a F1 SpinPoint hdd.

    Thanks,

    Nadeem

  • #800 / Apr 26, 2009 1:00pm

    OverZealous

    1030 posts

    @NachoF
    That is just a limitation on how DataMapper looks at relationships.  It cannot be changed without significantly altering the codebase.

    I think I mentioned in my sparse DMZ docs that you cannot have NOT NULL on related_id columns.  If that column allows NULLs, (and, I suppose, you set your foreign fields to allow 0 relationships), you won’t get errors.

    Alternatively, if you really want to avoid all of this, you can manually set the ids on the columns.  It actually works just fine:

    $object->related_id = $rel->id;
    $object->save();
    $object->related->get(); // will load in the related object

    @qureshi
    Why are you “unsetting” that variable?  There’s nothing to unset - it’s just an object reference to an object that is still in memory (in the ->all array).

    PHP has poor memory management, however, most users don’t have trouble unless they are trying to process hundreds of thousands of rows.  stensi did some tests earlier and didn’t have trouble.

    I don’t know how many objects you are doing, and there is no way to know from a code snippet if the error exists here or in something else you are doing.

    That being said, you could probably save a lot of memory by changing what you are doing.  For some reasons you are apparently trying to save every category to every translation of every verse.  But you are doing it in a round about way.  Instead, why not do this?

    $categories = new Cageory();
    $categories->get();
    $translations = new Translation();
    $translations->get();
    // or, to ensure that there is a related verse
    // $translations->where_related_verse('id >', 0)->get();
    foreach($translations->all as $tran) {
        $tran->save($categories->all);
    }

    This generates a whole lot less objects.

  • #801 / Apr 26, 2009 5:38pm

    reyntjensw

    12 posts

    I’d like to use this library, but I’m having some problems getting this to work.

    I’ve already have created my db like this:

    Contents
    - id
    - title
    - content_category_id

    Content_categories
    - id
    - title

    And my models look like this :

    <?php
    
        class Content extends DataMapper 
        {
            var $table = "Contents"
            var $has_one = array('content_category'=>'content_categories')
        
        function Content()
        {
            parent::DataMapper();
        }
        
        }
    
    ?>
    <?php
    
        class ContentCategory extends DataMapper 
        {
            var $table = "ContentCategory"
            var $has_many = array('content'=>'contents')
        
        function ContentCategory()
        {
            parent::DataMapper();
        }
        
        }
    
    ?>

    In my controller I query my db for all the content_category items

    $query = $this->db->get('content_categories');
    $data['results'] = $query->result_array();

    In my view, I loop through the results, but I can’t get all the content-entries to be displayed.

    <?php foreach($results as $result): ?>
        <?= $result['title']; ?>
    <pre>
        <?php print_r($result); ?>
    </pre>
    <p>    <?php foreach($result->content->get()->all as $content): ?><br /></p><pre>
            <?php print_r($content); ?>
        </pre>
    <p>    <?php endforeach; ?><br />
    <?php endforeach; ?>
    </pre>

    What am I doing wrong?

  • #802 / Apr 26, 2009 5:47pm

    OverZealous

    1030 posts

    This line:

    var $has_one = array('content_category'=>'content_categories');

    is wrong.  This hasn’t looked like this since DataMapper 1.2 or something.  Just make it this:

    var $has_one = array('content_category');
  • #803 / Apr 26, 2009 5:57pm

    reyntjensw

    12 posts

    I’ve changed that, but I’m still getting a Fatal error: Call to a member function get() on a non-object.
    Do I have to change some other things to?

  • #804 / Apr 26, 2009 6:03pm

    OverZealous

    1030 posts

    Well, most likely “content” isn’t set up correctly on whatever “result” is.  Look at your code, make sure you’ve correctly set up all relationships (on BOTH models).  Make sure that $result is a valid DataMapper model.

    Only you are going to be able to debug your code, because only you have access to it.

  • #805 / Apr 26, 2009 7:05pm

    MeanStudios

    335 posts

    I believe you are missing your relationship table between those two tabels.
    You need to created one called: content_categories_contents with the fields:
    id
    content_category_id
    content_id

    Also in your ContentCategory model, you need to name the class Content_category and the var $table should be “content_category”.  DataMapper is case sensitive.  I would recommend re-reading the General Topics on the manual.

  • #806 / Apr 26, 2009 7:27pm

    NachoF

    171 posts

    I have run into another problem now :(


    I have events and products, in a many to many relation…
    the thing is, the table events_products has one extra field called quantity… and I dont know how to add a value to that field.
    heres my controller function so far.

    function event_product()
    {
            $event=new Event();
            $product=new Product();
            //$event->get_by_id($this->input->post('event_id'));
            $event->get_by_id("1");
            $product->get_by_id($this->input->post('product_id'));
            $producto->save($evento);
    //where and how do I add quantity??
    }

    Please help.
    Edit: Nevermind, figured it out, set_join_field is awesome

  • #807 / Apr 27, 2009 1:33am

    MeanStudios

    335 posts

    Not able to use the class ‘Address’ as the inflector helper turns it into ‘Addres’.

  • #808 / Apr 27, 2009 1:36am

    OverZealous

    1030 posts

    @MeanStudios
    Make sure you are using the updated inflector helper included with DataMapper.  I’m pretty sure that handles “Addresses”.

    If that doesn’t work, then you can hard-code odd pluralizations directly into DataMapper, by setting $table on the class itself:

    class Address extends DataMapper {
        var $table = 'addresses';
        // var $model = 'address'; // also an option if needed
        ...

    Also, this is explained clearly in the documentation.

  • #809 / Apr 27, 2009 1:48am

    MeanStudios

    335 posts

    @OverZealous
    Yup, read over that very carefully and that’s why I am using var $table.  I didn’t know about var $model though.  That has fixed my problem.
    Address definitely doesn’t work with the updated inflector helper that comes with the latest DataMapper.

    It was trying to save to the field ‘addres_id’ in my relationship table as well. Once I used the var $model trick, everything works.

    Thanks for the info.

  • #810 / Apr 27, 2009 2:23am

    MeanStudios

    335 posts

    *removed*

    update:
    n/m, forgot a reciprocal $has_one definition 😉.

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

ExpressionEngine News!

#eecms, #events, #releases