Welcome Guest, Not a member yet? Register   Sign In
DMZ 1.7.1 (DataMapper OverZealous Edition)

[eluser]TheJim[/eluser]
I would say for your circumstances, what you're thinking is probably the right way to go about it. I'd maybe test it against the simple looping and querying method since it's easy to code, but with that many additional queries, I think you're almost guaranteed to be much faster with the extra logic.

[eluser]anaxamaxan[/eluser]
Oh, duh. Hey thanks TheJim. In spite of the red "warning" box in the docs, I never even noticed that include_related doesn't work with has_many relations -- I guess I've only used it with has_one since that's when it's most useful. Sorry about the noise.

[eluser]OverZealous[/eluser]
@anaxaman,TheJim,squawk

One of the things I am planning for the next version of DMZ is to remove the has_one restriction on include_related. The original reason for this restraint had to do with how objects were stored in the all array, but for a while now, DMZ would work fine with multiple results per id.

Of course, it won't do exactly what might be expected (unless I write a lot more logic in), since you'll get one row per unique result, even if that means multiple rows per id.

(I might add some logic in to optionally loop through the results and consolidate the rows when instantiating related items.)

But don't wait around on the next version... It might be until Fall before I can get to working on DMZ again.

[eluser]sqwk[/eluser]
More difficult that I thought;-) How can I get the just the places that are related to the buyers that I already have in one object? I found where_in_related, but I am not entirely sure on how to use it. And what logic would I need to loop through the buyers and add the relevant places? The problem that the actual linking info is in the join table so not in either two objects… Any ideas?

[eluser]TheJim[/eluser]
Something like:

Code:
// Load records into $buyers however you want
...

$ids = array();
foreach ($buyers as $b)
     $ids[] = $b->id;

$place = new Place();
$place->where_in_related('buyer', 'id', $ids)->get();

...

That may not have whatever nuances you might need for your situation, but I think it should get you pointed in the right direction.

[eluser]sqwk[/eluser]
Actually I whipped up this in the meantime:

Code:
foreach ($b as $row)
    $buyer_ids[] = $row->id;
$buyer_ids = implode(',', $buyer_ids);

$p = new Place();
$p->where_in_join_field('buyer', 'buyer_id', $buyer_ids);
$p->include_join_fields();
$p->get_iterated();

foreach ($b as $buyer)
    foreach ($p as $place)
    if ($buyer->id == $place->buyer_id)
            $buyer->place[] = $place;

This generates the following query:

Code:
SELECT * FROM (`places`) WHERE `buyers_places`.`buyer_id` IN ('353,348,347,346,345,…')

What would I need to JOIN the join table?

[eluser]TheJim[/eluser]
Oh, and you wanted to link them:

Code:
$place->where_in_related('buyer', 'id', $ids)->include_related('buyer', 'id')->get(); // or get_iterated if suitable
foreach ($place as $p)
{
    $b = $buyers->all[$p->buyer_id];
    ...
}

That would be one way to link if your configuration is set up to index the $all array by ID. That has consequences with getting multiple records in queries, so you might want to just make a simple reference map yourself when you're getting the IDs (or only doing the map and using array_keys, or whatever):

Code:
$ids = array();
$map = array();
foreach ($buyers as $b)
{
     $ids[] = $b->id;
     $map[$b->id] =& $b;
}

If there are any errors in my example code, sorry, but it should at least provide guidance.

[eluser]TheJim[/eluser]
It looks like you're manually joining them, but where_in_related would do that for you. To answer your question, you shouldn't have to add anything to the join table, you just have to include the Buyer ID in your query.

Also, your code

Code:
foreach ($b as $buyer)
    foreach ($p as $place)
        $buyer->place[] = $place;

will just give you all places for all buyers, not what you want.

[eluser]sqwk[/eluser]
Yes, I just saw that as well—edited the foreach and threw in an if.

Include_related won't work as it is a has_many relationship.

[eluser]TheJim[/eluser]
I see. I was thinking it was one-to-many for buyers to places, for whatever reason.

I'd probably still use where_in_related over where_in_join_field though. To me it adds clarity to the code, though you're of course welcome to do whatever you prefer.




Theme © iAndrew 2016 - Forum software by © MyBB