Welcome Guest, Not a member yet? Register   Sign In
DataMapper ORM v1.8.0

[eluser]DerLola[/eluser]
Alright, I wrote my own extension. It may be usefull to others. Also, do you see things that could be optimized? As I said, I'm quite new to ORMs.
Code:
<?php

class DMZ_Regular_Object {

/**
  *
  * @param DataMapper $object The DataMapper Object to convert
  * @param array $fields Array of fields to include.  If empty, includes all database columns.
  */
function to_object($object, $include_relations = FALSE, $recursive = FALSE) {
  
  // The main regular object
  $result = (object) array();

  // Loop through all fields
  foreach($object->fields as $field_name) {
  
   // just the field.
   $result->$field_name = $object->$field_name;
  }
  
  // Include the relations?
  if ($include_relations) {
  
   // Has many relations to arrays
   foreach ($object->has_many as $key => $value) {
    if ($object->$key->id) {
    
     // Create an array containing the objects
     $relations = array();

     // Add the objects
     foreach ($object->$key as $relation) {
      $relations[] = $relation->to_object($recursive, $recursive);
     }

     // Add to the value object
     $result->{$value['join_other_as']} = $relations;
    }
   }
  
   // Has one relations to single object
   foreach ($object->has_one as $key => $value) {
    if ($object->$key->id) {
     $result->{$value['join_other_as']} = $object->$key->to_object($recursive, $recursive);
    }
   }
  }

  return $result;
}
}

One more question about relations. I use ITFKs and it all works fine when it is called something like timeline_id, but I would like to use timelines_id. I check the advanced relationships docs, but couldn't figure out how to do this.

[eluser]WanWizard[/eluser]
I get the shivers when I see code like
Code:
$result = (object) array()
if you need an object, create one:
Code:
$result = new stdClass();

And I would combine the has_one and has_many in a single loop, and always return an array, whether there are none, one or more results. It will make your controller code a lot easier, as you don't have to test the return type first.

The ITFK's are defined in 'join_self_as' and 'join_other_as', and are the column name minus the "_id" suffix.

[eluser]DerLola[/eluser]
Thanks for your respone. I was not aware of the $result = new stdClass(); syntax. I guess you're never too old to learn Wink.

[offtopic]Is there also a syntax (other than array to object casting) to create an object with parameters? Like in JS: var object = {name: 'myname', age: 27}[/offtopic]

Thanks for your help, everything seems to be working properly now.


[eluser]WanWizard[/eluser]
Re: your offtopic question: no there isn't. stdClass is an empty generic class, the same as used internally by PHP when you cast something to object.

If you like JS, you could do
Code:
$object = json_decode('{name: "myname", age: 27}'); // note that strings need to use double quotes!
which will create the object from json.

But I think it's quite expensive to use this, as it has to parse the json. Casting an array to object might be faster.

[eluser]DocO[/eluser]
Apologies if this has been covered - not hitting on the right search terms if it is.

I'm new to DataMapper, and got it working relatively well enough for discrete objects. Now I'm trying to be able to create/edit objects that have relationships.

For example, I've got a Location model, that defines particular locations. It has_many another model, called Rack, which has_one Location.

In the controller/view for a Rack, I need to be able to create a selector of available Locations. I have a single view, called "edit.php", that handles both creating a Rack and editing it, and is fed off two functions - edit() and save() in the controller. If validation fails in save(), it loads up edit.php with the info again and the validation errors.

To generate the selector, I created a simple function in the Location model:

Code:
function get_list() {
                $list = $this->select('id,name')->order_by('name')->get();
                $mylist = array();
                foreach ($list as $obj) {
                        #echo $obj->id." ".$obj->name."<p>\n";
                        $mylist[$obj->id] = $obj->name;

                }
                return $mylist;
        }

In the controller for Racks, I simply create the Location object and call the function:

Code:
# Need list of locations
                $locs  = new Location();
                $data['location_list'] = $locs->get();

In the view, as long as there is validation error, I can reference the array in a foreach loop, and everything is fine - i.e., this simplified loop outputs what I expect:

Code:
&lt;?php foreach ($location_list as $loc): ?&gt;
            &lt;?php echo "ID $loc->id<p>\n";?&gt;
            &lt;?php echo "NAME $loc->name<p>\n";?&gt;
          &lt;?php endforeach ?&gt;

But if there is ANY validation error, apparently $location_list is completely different, and I get errors about trying to get the property of a non-object with reference to the $loc->id and $loc->name references.

I'm certainly not doing something right, but I can't understand why it works except if there is a validation error.

[eluser]DocO[/eluser]
Bah...my own fault. I swear I checked these several times, but in the working case I'm just calling "get()", not "get_list()". sigh.


[eluser]AAtticus[/eluser]
Is there a way to automatically/dynamically set all the attributes for a datamapper object instead of assigning them one for one?

So my form field names are exactly the same as the attributes from the datamapper model.

So is there a shorter way to do this:

Code:
function add() {
if( $this->input->post('client-add')) {
$c = new Client();
$c->name = $this->input->post('name');
$c->email = $this->input->post('email');
// and so on for about 20 more properties

$c->save();
  }

[eluser]WanWizard[/eluser]
Load the Array extension, then you can do
Code:
$c->from_array($this->input->post());

[eluser]AAtticus[/eluser]
Hi WanWizard, thanks for your reply, it works!


Another question,

I'm setting up relationships in my models using DataMapper but I've hit a wall.

I have a RealEstate class, a Client class and a Position class which all have many to many relationships because. A CLIENT can have the POSITION 'buyer' in a REALESTATE but the same CLIENT can have the position 'seller' in another REALESTATE, so for a given REALESTATE it's easy to find all the CLIENTs attached to it, but how can I also include that CLIENT POSITION for that specific REAL ESTATE?

[eluser]WanWizard[/eluser]
Not a problem, use an advanced relationship definition.

Check the docs, it has an example of a post that has both an author and an editor, two relations both pointing at the same model.

p.s. you are posting in a v1.8.0 thread, which is no longer the current version.




Theme © iAndrew 2016 - Forum software by © MyBB