• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
DataMapper multiple self relations

#1
[eluser]TomMRiddle[/eluser]
I am trying to understand how to make datamapper use the following relationship for movies, tvseries, seasons and episodes:
[Image: database.png]

1. I don't know how to make it use the type column for it to know what type it is and what it relates to.

2. How do I go about accessing child/parent objects in the controller when I only have one model.

Movie model:
Code:
<?php

class Movie extends DataMapper {


    var $has_many = array(
        'job' => array(),
        'comment' => array(),
        'tvseries' => array(
            'class' => 'movie',
            'other_field' => 'season',
            'join_table' => 'seasons_tvseries',
            'reciprocal' => TRUE
        ),
            'season' => array(
            'class' => 'movie',
            'other_field' => 'episode',
            'join_table' => 'episodes_seasons',
            'reciprocal' => TRUE
        ),
    );
    
    var $has_one = array(
        'season' => array(
            'other_field' => 'tvseries',
        ),
        'episode' => array(
            'other_field' => 'season',
        )
    );
    
    //var $has_many = array('mymovie');
    //var $has_one = array('subscribed');
    function __construct($id = NULL)
    {
        parent::__construct($id);
    }
}

?>

#2
[eluser]WanWizard[/eluser]
According to your database design, you have a many-to-many relationship to the Movie model, not a one-to many. So you have to define it as such.
Which will create the problem that your using the 'season' relation for two different tables, which is not going to work as you can define it only once.

I personally would implement this as a tree, since an episode can only belong to one season which only belongs to one serie. You can store a tree in a single table, and be more flexible. Have a look at the nested sets extension to deal with tree structures.

If you prefer join tables, I would implement this generic as well, and define a 'contains' and 'belongs_to' relation. And use a join field to define the type of relation if that is needed. In this case the definition would be
Code:
class Movie extends DataMapper {
    $has_many = array(
        'contains' => array(
            'class' => 'movie',
            'other_field' => 'belongs_to',
            'join_table' => 'movie_relations',
            'reciprocal' => TRUE
        ),
        'belongs_to' => array(
            'other_field' => 'contains',
            'join_table' => 'movie_relations',
            'reciprocal' => TRUE
        )
    );
}

Which needs a join table called 'movie_relations', containing the fields 'id', 'belongs_to_id' and 'contains_id'. You could add a join field called type.

So assuming that series have a type value of 'TVSERIE', you can get all series using
Code:
// get all TV series
$movie = new Movie();
$movie->contains->where_join_field('type', 'TVSERIE')->get();

disclaimer: I don't have access to a system to test this, I'm typing this from memory...

#3
[eluser]TomMRiddle[/eluser]
Thanks for the reply!

I think we have refined your idea with the movie relations table a little bit. since the depth for tv series tree will alwasy be the same and seasons are what connects series with episodes we thought we could just use that with belongs to foreign key to its tvseries parent and then a contains foreignkey to link the season to episodes and in extension also the episode to its series.

here is an updated version of the database:
[Image: databaseimproved.jpg]

we are struggling to understand how this is implemented in datamapper model in a way that makes sense to use in the controller. maybe you could point us in the right direction?

#4
[eluser]WanWizard[/eluser]
I still don't think it's going to work.

You can only define one self-relationship within a model, as the definition of one of the sides of the relationship must refer to the model itself. And you can use an array key only once.

#5
[eluser]Gamesh[/eluser]
it would be nice to have an example of one-to-many self relationship.

for example like ancestry tree, where you have one parent witch has many childs.

Code:
class Tree extends DataMapper {
    public $has_one = array(
    'parent' => array(
        'class' => 'tree',
        'other_field' => 'childs',
        'join_self_as' => 'parent'
    )
    );

    public $has_many = array(
    'childs' => array(
        'class' => 'tree',
        'other_field' => 'parent',
    )
    );
}

somehow i can't make this work. any suggestions? Smile


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2021 MyBB Group.