CodeIgniter Forums
DMZ 1.7.1 (DataMapper OverZealous Edition) - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: DMZ 1.7.1 (DataMapper OverZealous Edition) (/showthread.php?tid=28550)



DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-23-2010

[eluser]Colm Ward[/eluser]
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:
Code:
$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
Code:
$user->save();

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

Code:
$user->save($group);

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

Code:
$user->group = $group

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

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

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

Code:
$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


DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-23-2010

[eluser]OverZealous[/eluser]
@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.)


DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-24-2010

[eluser]Tom Vogt[/eluser]
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.
Code:
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?


DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-24-2010

[eluser]Colm Ward[/eluser]
@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


DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-24-2010

[eluser]Tom Vogt[/eluser]
Ah! I read the docs up and down, but missed this one. Thanks!


DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-24-2010

[eluser]broofa[/eluser]
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 Sad )

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


DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-24-2010

[eluser]lexusgs430[/eluser]
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.


Code:
$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
            }
        }



DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-24-2010

[eluser]OverZealous[/eluser]
@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. ;-)


DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-25-2010

[eluser]Skipper[/eluser]
[quote author="OverZealous" date="1277142198"]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.[/quote]

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


DMZ 1.7.1 (DataMapper OverZealous Edition) - El Forum - 06-25-2010

[eluser]OverZealous[/eluser]
@Skipper
Something like this might work:
Code:
// 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 Smile