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.

DMZ 1.7.1 (DataMapper OverZealous Edition)

March 14, 2010 11:43pm

Subscribe [104]
  • #796 / Jan 03, 2011 7:24pm

    WanWizard

    4475 posts

    The short answer is, you can’t on a many-to-many. Since every record is an object, the number of objects in memory would explode.

    Many to one’s can be ‘pulled’ into the result using include_related(). You can use the $instantiate parameter to have it included as an object instead of adding the fields to the current object. Theoretically include_related could deal with has_many (there an ticket open on that), but you’ll soon run into the aformentioned issue.

  • #797 / Jan 03, 2011 10:52pm

    Guido Mallee

    14 posts

    I understood. Though, the way I do it in my example code is just as memory intensive as it would be if ‘the easy way’ would have been possible, isn’t it?

    Since the relation of my table BLOCKS to my table BLOCK_TEXTS actually is one-to-‘one or zero’ (one-to-many but never more than 1 result) I tried to use include_related. As you mentioned though, this didn’t work since the relationship theoratically still is one-to-many. I couldn’t find the ticket about using include_related with has_many (hate the search functionality on this forums, or is it just me?). Could you pass me the link, please? I think I’ll give that a try since, like I said, the result will be only one row maximum, and therefore, one object maximum. No problem, right?

    I finished porting one of my websites with CMS to DataMapper and I’m really enthusiastic about it! I think DataMapper is going to save me a lot of work in the future. Many thanks, WanWizard, for all your dedicated work on this great ORM, and of course, for your great support. One (hopefully) last question, though:

    Remember I asked you about the joining field? I have a joining field ‘position’ in the joining table between the tables PAGES and BLOCKS. I managed to easily get all blocks from a page, ordered by position. To save a new block though, I had to get the max position of a block on a specific page first, which turned out to be quite hard. I ended up doing:

    $page = new Page($page_id);
    $page->block->include_join_fields()->get();
    $position = 1;
    foreach ($page->block as $b)
    {
        if ($b->join_position > $position)
            $position = $b->join_position;
    }
    $position++;
                
    $block->save($page);
    $block->set_join_field($page, 'position', $position);

    Where I’d much rather would like to do something like:

    $page = new Page($page_id);
    $page->block->select_max('position');
    $page->block->include_join_fields()->get();
    $position = $page->block->join_position + 1;
    $block->save($page);
    $block->set_join_field($page, 'position', $position)

    This didn’t work though. It’s not a disaster to do it like in the first piece of code, although, getting the max position used to be one line of code for me before. Is there a way to refactor this code?

    Thanks in advance and I’ll try hard to leave you in peace after this one.

  • #798 / Jan 04, 2011 9:51am

    Dennis Rasmussen

    601 posts

    Love the library and been reading the docs several times now.

    I’m having a “small” issue with the naming conventions and I’m wondering why noone else seems to have encountered this problem.

    Basically, what do you guys do if you want a controller with the singular name of a table name?
    An example would be /user/view/1 with a table name of users.
    That would then require the model name to be the same as the controller name giving you an error - unless you write a custom model name and specify a table within the model. But if you do this then how do you setup relations? For the custom model name or?

    $has_many = array('user_model');

    I’m a bit lost on what to do here because I ended up having so many errors because of my custom model names to avoid class name collisions.

    With Yorick’s ORM you don’t have this issue as he requires model suffixes (https://github.com/YorickPeterse/Awesome-Record), so am I missing something with DataMapper?


    Second question:
    Let’s say I have a forum where you want to iterate through categories then forums within. How do you iterate like that with an ORM? Get the cateogory and foreach - then get the forums in the category and foreach?

  • #799 / Jan 04, 2011 9:55am

    WanWizard

    4475 posts

    If the relation is one-to-one-or-zero, why define it as has_many? Include_related only works on has_one.

    You can find Datamapper’s issue tracker on http://bitbucket.org/wanwizard/datamapper/issues.

    As for the join_field, I understand the issue. If you just want the highest position, you could try order_by(‘position’, ‘DESC’)->limit(1) to get only that record.

  • #800 / Jan 04, 2011 10:03am

    WanWizard

    4475 posts

    @Dennis,

    If you want to deviate from the naming conventions, you can manually define the table name in the model. As long as you don’t have any relationships, that will work.

    If you do have relationships, you have to switch from simple definition (i.e. using just the model name) to the advanced form (using an array to define the relation). With the advanced form you are free to define the model name, and the column names that are used to define the relationship. See http://datamapper.exitecms.org/pages/advancedrelations.html for more information.

    Maybe I should add a section to the manual about this specific issue.

  • #801 / Jan 04, 2011 10:26am

    Guido Mallee

    14 posts

    Heck, of course that isn’t a has_many relationship. Thanks!

    The order_by and limit also did the trick there!

  • #802 / Jan 05, 2011 11:11am

    Colm Ward

    12 posts

    Hi Folks

    Apologies if this is a stupid question. Is there any convenient way I can override or overload save()?

    The docs explicitly says that an extension will not overwrite a DataMapper method, so I can’t do it that way. I could modify save() in the core Datamapper library but I’d rather not mess with that. I could do it in each model but I have a lot of models so that’s a lot of duplicate code.

    Any ideas?

  • #803 / Jan 05, 2011 11:53am

    The Hamburgler

    28 posts

    I would extend the Datamapper class with your own library, and then have your models extend from the new class.

    When I have done this previously I have added code to the classes constructor to prevent the object looking for a table called datamapper_ext.

    class DataMapper_Ext extends DataMapper {
    
        public function __construct($id=NULL)
        {
            if(get_class($this) == 'DataMapper_Ext')
                return;
            
            return parent::__construct($id);
        }
    
    }

    Hope that helps

  • #804 / Jan 05, 2011 12:11pm

    Colm Ward

    12 posts

    Excellent, thanks for that. Will give it a shot. I did indeed get caught out with a non existent table being looked for when I tried it that way, so thanks for the tip.

    I’m trying to build in access control to models by overloading save() and get(). The basic idea is, if the logged in user is allowed to ‘read’ the model they are retrieving, go ahead with the regular get() in the parent. Same thing with overloading save() to handle write access.

    Hopefully it will work! 😊

  • #805 / Jan 07, 2011 7:32pm

    PoetaWD

    97 posts

    Double posted….

  • #806 / Jan 07, 2011 7:35pm

    PoetaWD

    97 posts

    Is there a way to get the id after save() ??

    I am building a form that dinamicaly adds records to a table.

    After the record is saved, it will return the ID of the created record and append it to the form.

    It will send this ID as a $POST and will save the form data related to the dinamicaly created record.

    Is it possible to be made ?

  • #807 / Jan 07, 2011 8:14pm

    Dennis Rasmussen

    601 posts

    Is there a way to get the id after save() ??

    I am building a form that dinamicaly adds records to a table.

    After the record is saved, it will return the ID of the created record and append it to the form.

    It will send this ID as a $POST and will save the form data related to the dinamicaly created record.

    Is it possible to be made ?

    After you save(), the object will have its new ID added.

    $user = new User();
    $user->name = "mr bean";
    $user->save();
    
    echo $user->id; // the new ID
  • #808 / Jan 08, 2011 4:11am

    tdktank59

    322 posts

    Ok I must be going insane or something.
    I think this used to work at least lol…

    Ive got 2 tables
    users and statuses
    they have a many to one relation (each user can have a status)

    On the user table there is the field status_id

    I am trying to pull the status for the user like this

    This one does not work I get the error
    “DataMapper Error: ‘User’ is not a valid parent relationship for Status. Are your relationships configured correctly?”

    $user = new User();
    $user->get_by_id(1);
    $user->status->get();
    
    $user->status->name;

    However going from the status it works…

    $status = new Status();
    $status->get_by_id(2);
    $status->user->get();
    foreach ($status->user as $user) {
        print $user->username;
    }

    So just wondering whats going on, and want to make sure im not imagining things.
    The models are setup properly
    user: $has_one = array(‘status’);
    status: $has_many = array(‘user’);

  • #809 / Jan 08, 2011 6:38am

    WanWizard

    4475 posts

    I think you have to re-check everything, you must be missing something obvious.

    The code above, with the corresponding model files and relationship definitions, works fine here.

  • #810 / Jan 08, 2011 5:35pm

    tdktank59

    322 posts

    I think you have to re-check everything, you must be missing something obvious.

    The code above, with the corresponding model files and relationship definitions, works fine here.

    I thought as much, which is why I was pulling my hair out. Turns out the $model in the user script was $model = “User”; instead of “user” which caused the issue.

    Thanks

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

ExpressionEngine News!

#eecms, #events, #releases