Welcome Guest, Not a member yet? Register   Sign In
What is the most efficient way to load multiple has_many relationships in DataMapper ORM
#1

[eluser]Unknown[/eluser]
Given the following models:

Category: has_many('template')
Template: has_many('tag', 'procedure')

What is the most efficient way to load ALL object related to ALL categories?

For instance, I'm currently doing the following, but hopefully there is a better way:

Code:
// Load all Category objects
$categories = new Category();
$categories->get();

// Load all Template objects related to each Category
foreach($categories as $category)
{
  $category->templates->get();

  // Load all the Tag and Procedure objects related to each template
  foreach($category->templates as $template)
  {
    $template->tags->get();
    $template->procedures->get();
  }
}
#2

[eluser]WanWizard[/eluser]
Use include_related(), it will produce a single join.
#3

[eluser]darkylmnx[/eluser]
@WanWizard, include_related() seems to give access to only the first row of the full result either by the $object->all load or the $object loop.

Is there another effective way ?
#4

[eluser]WanWizard[/eluser]
The hydration method can't deal with repeated information, because it doesn't split the query result into related objects. It can only store a records with a 'parent' primary key only once, so other rows in the result with that same primary key will be ignored.
#5

[eluser]darkylmnx[/eluser]
[quote author="WanWizard" date="1363159865"]The hydration method can't deal with repeated information, because it doesn't split the query result into related objects. It can only store a records with a 'parent' primary key only once, so other rows in the result with that same primary key will be ignored.[/quote]

so eager load on multiple objects is not possible, mmmh

a fork like Model::with('relation')

could be a good idea i guess.
#6

[eluser]WanWizard[/eluser]
You can't do eager loading of many-to-many's, you can for the others, if you use the 'instantiate' flag on the include_related() call.

A fork is a bad idea, if you want to address this, check the _process_query() and _to_object() methods, create a fix, and send a pull request.

I don't have time for it, new Datamapper features are at the bottom of my todo list atm...
#7

[eluser]darkylmnx[/eluser]
[quote author="WanWizard" date="1363194745"]You can't do eager loading of many-to-many's, you can for the others, if you use the 'instantiate' flag on the include_related() call.

A fork is a bad idea, if you want to address this, check the _process_query() and _to_object() methods, create a fix, and send a pull request.

I don't have time for it, new Datamapper features are at the bottom of my todo list atm...[/quote]

are you working on another orm ?
#8

[eluser]darkylmnx[/eluser]
[quote author="WanWizard" date="1363194745"]You can't do eager loading of many-to-many's[/quote]

you can't for the one-to-many either
#9

[eluser]WanWizard[/eluser]
[quote author="darkylmnx" date="1363197828"]
you can't for the one-to-many either[/quote]

Something like this should work without problems, it always has:

Code:
// Create User
$u = new User();

// add the group id and name to all users returned
$u->include_related('group', array('id', 'name'), TRUE, TRUE)->get();

foreach($u as $user) {
    echo("{$user->group->name} ({$user->group->id})\n");
}

#10

[eluser]WanWizard[/eluser]
[quote author="darkylmnx" date="1363197748"]are you working on another orm ?[/quote]
I am project lead for another framework.

Which includes an ORM. Which in the next version will no longer have framework dependencies, so it could be used with other frameworks as well.

So indirectly, yes. Wink




Theme © iAndrew 2016 - Forum software by © MyBB