Edit 3
After reading a boat load I really don't think with any ORM or system in general it is possible to build the relationships of organized objects like I want in fewer queries that I am using. If any can provide an example of it being possible I would kiss you.
In Edit 2 The nested for loops I think is the best solution running
Total_queries = 1 + 2(Slides_in_project) + Shapes_in_project
| | \
Query to get project | \
| \
Query to get slides and double because of points \
\
Get all the shapes in the project
I would love a better example because to populate simple projects I would probably be running 200-500 queries. This is bad.
Edit 2
Well I have been playing with this for a while now and I have some results but I do not think they are the "RIGHT" way and that matters to me a lot. What I do is I use the where_related
method to get the right objects but I think my query count is still pretty high and I know an ORM can do better. When I use the where related to create the proper hierarchy I have to use nested foreach
loops and I don't like that. That means useless querying.
Here is the solution I came up with
function get_project_points($link_id)
{
echo "<pre>";
foreach($this->where('link_id', $link_id)->get()->slide->where_related('project', 'id', $this)->get() as $slide){
echo $slide->id."<br>";
foreach($slide->shape->where_related('slide', 'id', $slide->id)->get() as $shape){
echo "\t".$shape->id."<br>";
foreach ($shape->point->where_related('shape', 'id', $shape->id)->get() as $point) {
echo "\t\t".$point->id."<br>";
}
}
}
}
This outputs a nice tiered structure and as you can see it would be easy to replace the echos with object/array population.
What I would rather have though is one chained command that did the same thing if possible that way scoping isn't an issue either.
Some chain more resembling
$this->where('link_id', $link_id)->get()
->slide->where_related('project', 'id', $this)->get()
->shape->where_related('slide', 'id', $slide->id)->get()
->point->where_related('shape', 'id', $shape->id)->get()
That of course does not achieve anywhere near the same results as the nested foreach loops but what I would like to know is it possible to chain relationships and populate objects without nested foreach
So I just did some profiling and the nested foreach loops generate 63 queries on a small project, and take almost half a second to generate results. This is really too slow. There must be a better query.
__________Edit 1
All the below information is great but I have been playing with it and I cannot seem to get any relationship to work let alone a 3 tiered one. I have tried just about everything I can think of and read the doc's but for somereason my brain doesn't like the ORM.
I would like to just echo the id's of all slides
in a project
. I will give a list of what I have tried with no avail. My model structure is the same as below I am just adding methodes.
class Project extends DataMapper {
var $has_many = array("slide");
function get_project_slides($link_id)
{
$this->where('link_id', $link_id)
->where_related('slides', 'project_id'
$this->where('link_id', $link_id)->get()->id
)
->get();
}
}
And I have tried what I would think is the logical opposite in the Slide Method.
What am I doing wrong... How do you structure ORM relationships?
Original Question
I am using an ORM for the first time and I am having huge problems visualizing how to structure the code to pull data from the relationships.
I am using DataMapper as my ORM with CodeIgniter. I have the installation working just fine and I read all the docs, I just cannot get my head around how to get information in controllers
+-----------+ +------------+ +---------+ +----------+
| projects | | slides | | shapes | | points |
+-----------+ +------------+ +---------+ +----------+
| id | | id | | id | | id |
+-----------+ | project_id | |slide_id | | shape_id |
+------------+ +---------+ | x |
| y |
+----------+
Models -
project.php
class Project extends DataMapper {
var $has_many = array("slide");
}
// End of project.php
// Location: ./application/models/project.php
slide.php
<?php
class Slide extends DataMapper {
var $has_many = array("shape");
var $has_one = array("project");
}
// End of slide.php
// Location: ./application/models/slide.php
shape.php
<?php
class Shape extends DataMapper {
var $has_many = array("point");
var $has_one = array("slide");
}
// End of shape.php
// Location: ./application/models/shape.php
point.php
<?php
class Point extends DataMapper {
var $has_one = array("shape");
}
// End of point.php
// Location: ./application/models/point.php
The above should create a decending one->many relationship between projects->slides->shapes->points
How do you start to deal with information? When I was not using an ORM I handled all data processing in the Model is this incorrect for the ORM Models? Say you wanted to get all the points in all the shapes in project 1 how would you go about structuring such a call?
I don't really need specific code if you want that would be helpful. What I really need is some ideas on how to visualize how to tier the objects so you can deal with each at any tier.