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]
  • #361 / Jun 23, 2010 12:45pm

    Colm Ward

    12 posts

    Hi

    Is it possible to set up a relationship between objects without saving those objects?

    Say I have users and groups as models with a one-to-many relationship (each user belongs to one group).

    If I want to create a new user, I can set the various properties on the $user object first, and then save later.
    eg. I can go:

    $user->firstname = 'Joe';
    $user->surname = 'Bloggs';

    etc. which sets the values on the model, but doesn’t save it. I can then pass this object around to various functions, in different scopes, to set more of the properties.

    When I’m finally happy with the state of the model, I can save it to the database with

    $user->save();

     
    If however, I want to relate the user to a group, I have to save it right away:

    $user->save($group);

    If possible, I’d like to just set up the relationship in the user object, doing something like this:

    $user->group = $group

    without saving, and then continue to modify the $user properties: 

    $user->firstname = 'John';
    $user->surname = 'Doe';

    until finally saving both the $user and its relationship to the group with

    $user->save();


    The reason I’m looking for this functionality is, I’m setting different user properties and relationships in different places in the code. Some properties, and some relationships, are set in controller functions, and some are set in model methods. For db performance reasons, I dont want to have to save the same user object every time I change scope.

    I tried doing the $user->group = $group thing, but it didn’t pass the validation (group is required on my user model). I also tried setting the $user->group_id but that didn’t pass validation either.

    Do you have any suggestions?

    cheers,
    Colm

  • #362 / Jun 23, 2010 1:41pm

    OverZealous

    1030 posts

    @Colm Ward

    Short answer: no.  It says this explicitly in the docs.

    Longer answer: It might not matter.  Calling ->save() on an object doesn’t necessarily write anything to the DB.  It only processes the actual update if something has changed.

    But saving the relationship between two objects requires that both objects exist in the database.  Also, transactions can help a lot, by allowing you to make ‘temporary’ saves that are atomically committed.  Of course, your database needs to support transactions and handle them well.

    Another option is to pass an array around with your functions, then save all the objects at once (see the section on saving relationships for more info.)

  • #363 / Jun 24, 2010 5:07am

    Tom Vogt

    49 posts

    posting here as well, since this thread seems to be active:

    I’m wondering if this can be done with DMZ or if I have to add yet another table:

    I have a user table and an object table that are joined via a join table, due to a many-to-many relationship (a user can have access to many objects, each object can be accessed by many users).

    I would like to “qualify” the type of access that a user has. This is not a generic role that spans objects, but is always object-specific. So user A may be admin of object B, but only a regular user on object C.

    My intuitive solution was to expand the join table by an access level, i.e.

    object_id
    user_id
    access_level

    But I have not found a way to use this through DMZ. Did I miss something, or is there a better way to do it?

  • #364 / Jun 24, 2010 7:19am

    Colm Ward

    12 posts

    @Phil:
    Thanks for the advice, will look into your suggestions. I’m using DMZ in a project I’ve been working on every day for the last few months. Its a big help


    @Tom Vogt:

    Check out “Working with join fields” in the manual:
    http://www.overzealous.com/dmz/pages/joinfields.html

  • #365 / Jun 24, 2010 9:58am

    Tom Vogt

    49 posts

    Ah! I read the docs up and down, but missed this one. Thanks!

  • #366 / Jun 24, 2010 1:32pm

    broofa

    6 posts

    Hi, I’m trying to upgrade from the stensi.com version of DM to the DMZ version and would like to share some feedback since it’s not going as smoothly as I had hoped.

    First, it’s not exactly easy to discover that DMZ is the natural successor to stensi.com’s original DM implementation.  It’d be really nice if there were a big, fat, “Deprecated!” message on stensi.com that linked to the DMZ site. (The only reason I’m on the stensi version is that I didn’t discover DMZ implementation until today :( )

    As far as the upgrade, my code is pretty basic, as is my DB configuration.  I was hoping this would be a simple matter of replacing a couple files (as per upgrade instructions).  However, here are the stumbling blocks I’ve encountered so far (using CI 1.7.2, fwiw)...
    - The instructions for the new config options make it sound like there are reasonable defaults chosen for you if you want to just leave your old config file in place.  That’s not the case - you get errors if some of the new options aren’t defined, so it probably makes sense to tell people to migrate their old options into the new config file.
    - With default lang_file_format setting, I get “Call to a member function item() on a non-object” error @ datamapper.php:484.  Using $config[‘lang_file_format’] = ‘’ fixes the problem.
    - With dp_params=’’ I get “Undefined property: Entry::$db” error @datamapper.php:1063.  Using $config[‘db_params’] = FALSE fixes the problem.

    And, having worked through the above, I’m now getting “Call to a member function line() on a non-object” @ datamapper.php:5707.  I’m not sure what the problem is yet, but I have to think at this point that I’m missing some vital configuration step that’s causing me to run into this series of errors.

    So what am I doing wrong?

    - rwk

  • #367 / Jun 24, 2010 9:21pm

    lexusgs430

    49 posts

    Is get_iterated allowed to be used in conjunction with where? I am having trouble with a script that is returning no errors and is silent failing. Code is below.

    $items = new item();
            $items->where('style_id', $style_id);
            $items->get_iterated;
            
            if(!$items->exists()) {
                echo('No Items');
            } else {
                echo($items->result_count() . ' items were found.');
                foreach($items as $item) {
                
                  $id = $items->id;
                  $items->_create_image_thumb_name($id);
                  echo "image created";
                    // process like normal
                }
            }
  • #368 / Jun 24, 2010 11:31pm

    OverZealous

    1030 posts

    @broofa
    Well, I don’t have any control over what stensi does with his domain.  I don’t understand why you would assume that…  And DataMapper isn’t deprecated.  It’s just not upgraded any more.

    As for your configuration problems, I’m sorry but the very first item in the upgrade process tells you to update your datamapper config.  And the config page explicitly lists the items that are new to DMZ.

    As for your other errors, you probably need to spend some time reading the manual.  Setting db_params to FALSE is not recommended, and just not necessary since 1.7.

    (Also, there have been 5 or 6 major revisions to DMZ since DataMapper was last released, so it’s probably not quite as smooth. 😉 )

    @lexusgs430
    The get_iterated method works with just about anything that works with a normal get.  However, you aren’t actually calling the function above, since you don’t have any parentheses.  Try calling the method, instead of referring to a non-existent property. 😉

  • #369 / Jun 25, 2010 3:58am

    Skipper

    6 posts

    Sounds like that would be a great case for a DMZ extension. ... You’d probably want to cache the results of the enum lookup somehow.

    Ok, I will write such an extension. Do you have any preferences/suggestions how to cache the results?

  • #370 / Jun 25, 2010 8:41am

    OverZealous

    1030 posts

    @Skipper
    Something like this might work:

    // in the extension class
    public static $enum_cache = array();
    
    private _get_enum($object, $field) {
        if(!isset(EXTENSION_CLASS_NAME::$enum_cache[$object->model])) {
            EXTENSION_CLASS_NAME::$enum_cache[$object->model.'-'.$field] = ...
        }
        return EXTENSION_CLASS_NAME::$enum_cache[$object->model.'-'.$field];
    }

    Then just use the _get_enum method to determine the values.  That’s just an example.  You might want to make that method public (and therefore remove the leading _), so it can be used for other reasons, too.

    Edit: Don’t forget to include the field name in the cache, like I did…  I updated the code 😊

  • #371 / Jun 25, 2010 12:29pm

    broofa

    6 posts

    Thanks for the quick reply, Phil. 

    Well, I don’t have any control over what stensi does with his domain.  I don’t understand why you would assume that…  And DataMapper isn’t deprecated.  It’s just not upgraded any more.

    ‘Wasn’t assuming you had control over stensi.com.  Rather, it’s pretty clear you’re carrying the baton on this codebase now.  So sending an email to stensi.com asking that he point people to the DMZ site would seem an obvious thing to do (especially since you don’t show up in the first page of google results for “php datamapper” and stensi.com does).  I’m happy to do that if you’d like, but it would make more sense if that came from you.

    As for your configuration problems, I’m sorry but the very first item in the upgrade process tells you to update your datamapper config.  And the config page explicitly lists the items that are new to DMZ.

    By documenting “default” values for these parameters you set up the expectation that they aren’t required.  (That’s what “default” means). So either the code should change to provide default values when none are found in the config file, or docs should describe these as required properties with “suggested” values.

    As for your other errors, you probably need to spend some time reading the manual.  Setting db_params to FALSE is not recommended, and just not necessary since 1.7.

    While it’s entirely possible my problems are specific to my application, this isn’t a problem of me not having read the manual. ‘Read it several times.  And I’m now at the point where I’m stepping through DMZ and CI code trying to understand what I might be doing wrong.  Unfortunately with the default config settings, I’m seeing errors.  That’s the *only* reason I’m using the FALSE value for db_params, and also the only reason I have lang_file_format=’‘.  If you have better suggestions for how to avoid (or understand what might be causing) these errors, I would love to hear them.  (e.g. is it possible there’s something different in CI 1.7.2 that might be causing these?)

    Cheers,

    - rwk

  • #372 / Jun 25, 2010 12:35pm

    broofa

    6 posts

    Quick followup to my previous post…

    It seems that some of these errors are a result of $CI->config being undefined when _assign_libraries() is called by the DataMapper constructor.  Any idea what might be causing that?

    - rwk

  • #373 / Jun 25, 2010 6:52pm

    TheJim

    35 posts

    Quick followup to my previous post…

    It seems that some of these errors are a result of $CI->config being undefined when _assign_libraries() is called by the DataMapper constructor.  Any idea what might be causing that?

    - rwk

    That’s odd.  I think you mentioned using CI 1.7.2 in your earlier post, which I also use, and which I believe (though I could be wrong) Phil uses as well.  So I wouldn’t think it has to do with your version of CI.

    Could you be trying to instantiate DMZ objects before CI is fully initialized?  Say, in a pre-system hook or in a controller’s constructor without first calling the parent’s constructor.  Anything like that?

  • #374 / Jun 25, 2010 7:11pm

    broofa

    6 posts

    Quick followup to my previous post…

    It seems that some of these errors are a result of $CI->config being undefined when _assign_libraries() is called by the DataMapper constructor.  Any idea what might be causing that?

    - rwk

    That’s odd.  I think you mentioned using CI 1.7.2 in your earlier post, which I also use, and which I believe (though I could be wrong) Phil uses as well.  So I wouldn’t think it has to do with your version of CI.

    Could you be trying to instantiate DMZ objects before CI is fully initialized?  Say, in a pre-system hook or in a controller’s constructor without first calling the parent’s constructor.  Anything like that?

    I found the problem.  I incorrectly implemented a __set method in my DataMapper subclass which was causing the DM reference to the $CI->config object (set in _assign_libraries) to be set to null.  Thus producing the “non-object” errors I kept seeing elsewhere.

    So… pretty much my own fault after all.  Shoulda known I guess, but in my defense this wasn’t exactly the most obvious bug.  Regardless, my apologies for bothering folks - everything’s working just peachy now!

    - rwk

  • #375 / Jun 27, 2010 12:51pm

    lexusgs430

    49 posts

    Question:

    Everythings been going smoothly til last night. I got a called to undefined function error in one of my models and no matter what I do I cant seem to fix it. (all the other models/controllers have been working fine.

    Fatal error: Call to undefined method Style::_get_style_by_sku()

    Anyone have any idea in general what can cause an error like this in just one model?

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

ExpressionEngine News!

#eecms, #events, #releases