Welcome Guest, Not a member yet? Register   Sign In
DataMapper ORM - get() question
#1

[eluser]madwhistler[/eluser]
Hi, I'm hoping that WanWizard or another experienced soul might offer me a bit of help on a DataMapper (1.7.2) snarl-up I'm trying to figure out.

It seems simple but I can't get this to work.

I have two Model classes, Asset and Client - Asset has_one Client, Client has_many Assets. (actually Asset has potentially two Client relations, tagged as owner and buyer, with owns_asset and buying_asset as the reverse relations. This all seems to work).

I'm selecting a set of Assets, and I want to find the corresponding set of Clients (by the owner relationship). My code snip:
Code:
$assets = new Asset();
$assets->run_filter(); // this does a where(xxx)->get_iterated()
echo 'Assets selected: '.$assets->result_count().'<br />';
$clients = $assets->owner->get(); // get my related owner clients
echo 'Clients selected: '.$clients->result_count().'<br />';

For my test filter this returns:
Quote:Assets selected: 35
Clients selected: 0

I'm expecting 35 clients (maybe less if there are duplicate owners).
Now, if I change run_filter() to do a get() rather than a get_iterated() I get "Clients selected: 1" instead -- only the first Asset's owner is selected. I've also tried some variants with "->all" but no luck.

Any clues as to what's wrong? All these assets definitely have owners...

Thanks for helping!!
#2

[eluser]WanWizard[/eluser]
$assets->owner gets the related owner of the 'current' asset, not of all assets in the resultset. That's why you get 1 in the get() example.
If you want all of them, you have to itterate over the assets and fetch the owners one at the time.

If you use get_iterated(), the assets object is not populated at all, but the results are fetched (one by one) as you iterate over the object. That's why you get 0, there is no 'current' asset ($assets->id will return null).
#3

[eluser]madwhistler[/eluser]
Thanks for the quick reply! So to tackle the "all owners of these assets" query, is there any shorthand that takes advantage of DMO's awesome features? My first thought is:
Code:
$assets->run_filter(); // using get_iterated()
foreach ($assets as $asset)
   ;// add the $asset->id to an array $ids

$clients = new Client();
$clients->where_related_in('owns_asset','id',$ids)->get()
echo $clients->count_distinct(); // in case one client owns several assets

Seems like a lot of work, though, for what's basically a join...I guess I could select the clients when I do the get() inside my filter, but I don't know at that point whether I *want* the clients.
#4

[eluser]WanWizard[/eluser]
If it's a has_one relationship (from asset to client/owner), you can use include_related() instead, which will make it a join.
Code:
$assets = new Asset();
$assets->where(xxx)->include_related('owner')->get_iterated();
See the manual for more info. You might try the $instantiate parameter to have objects created for 'owner' instead of including the fields in the result.
#5

[eluser]madwhistler[/eluser]
Thanks very much for the advice! Because I've already filtered the assets, I didn't want to rerun the query (which could be a substantial query in the final system). I chose to go with my original approach, collecting the asset ID's and doing the client get (with the necessary change from where_related_in to where_in_related ;P ) Seems to work.




Theme © iAndrew 2016 - Forum software by © MyBB