many-to-many relationship

25 views
Skip to first unread message

Andrea Guidoni

unread,
Jun 30, 2010, 1:23:33 PM6/30/10
to Outlet ORM
Hi, I'm Italian student, sorry my english...
I get the following result:
Collection Object ( [storage:ArrayObject:private] => Array ( ) )
But it is not right, I have made some mistakes in the many-to-many...

here's what I did:

//---------------------------------------------------------------------------------------------------
index.php

<?php

function __autoload($class_name) {
$a = "./" . $class_name . ".php";
if(file_exists($a)) require_once $a;
}


ini_set('display_errors',true);


require 'outlet/Outlet.php';
Outlet::init(include 'Outlet/outlet-config.php');

$con = Outlet::getInstance();

$d = new Developer();
print_r( $listWS = $d->getWorkSpaces('WHERE {Developer.ID} = 1') );

?>

//-------------------------------------------------------------------------------------------------------------------
outlet-config.php

<?php

return array(

'connection' = array(

'dsn' => 'mysql:host=localhost;dbname=example',
'username' => 'root',
'password' => '',
'dialect' => 'mysql'

);

'proxies' => array(
'autoload' => true
),

'classes' => array(

//Start Class Developer
'Developer' => array( //nome model class
'table' => 'Developer', //nome tabella presente in DB
'props' => array(
'ID' => array('ID', 'int', array('pk'=>true,
'autoIncrement'=>true)),
'Name'=> array('Name', 'varchar'),
'Surname'=> array('Surname', 'varchar'),
'Password'=> array('Password', 'varchar')
),
'associations' => array(
array('many-to-many', 'WorkSpace',
array('table'=>'WorkSpaceDeveloper','tableKeyLocal'=>'IDDeveloper','tableKeyForeign'=>'IDWorkSpace'))
)
),
//End Developer

//Start Class WorkSpace
'WorkSpace' => array( //nome model class
'table' => 'WorkSpace', //nome tabella presente in DB
'props' => array(
'ID' => array('ID', 'int', array('pk'=>true,
'autoIncrement'=>true)),
'URL'=> array('URL', 'varchar')
),
'associations' => array(
array('many-to-many', 'Developer',
array('table'=>'WorkSpaceDeveloper','tableKeyLocal'=>'IDWorkSpace','tableKeyForeign'=>'IDDeveloper'))
)

),

)
);

?>

//--------------------------------------------------------------------------
Developer.php

<?php
class Developer {

public $ID;
public $Name;
public $Surname;
public $Password;

//MANY-TO-MANY
private $WorkSpaces;

public function __construct() {
$this->WorkSpaces = new Collection();
}

public function getWorkSpaces() {
return $this->WorkSpaces;
}
public function setWorkSpaces(Collection $WorkSpaces) {
$this->WorkSpaces = $WorkSpaces;
}
}
?>

//------------------------------------

You could give me some advice?

Thanks
Andrea

Andrea Guidoni

unread,
Jul 1, 2010, 6:09:51 AM7/1/10
to Outlet ORM
look this please

//--------------------------------------------------
CREATE TABLE IF NOT EXISTS `Developer` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(30) CHARACTER SET utf8 NOT NULL,
`Surname` varchar(30) CHARACTER SET utf8 NOT NULL,
`Password` varchar(11) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;


INSERT INTO `Developer` (`ID`, `Name`, `Surname`, `Password`) VALUES
(1, 'Mario', 'Verdi', 'mario'),
(2, 'Franco', 'Rossi', 'franco'),

-- --------------------------------------------------------

CREATE TABLE IF NOT EXISTS `WorkSpace` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`URL` varchar(100) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

INSERT INTO `WorkSpace` (`ID`, `URL`) VALUES
(1, 'uno'),
(2, 'due');

-- --------------------------------------------------------

CREATE TABLE IF NOT EXISTS `WorkSpaceDeveloper` (
`IDDeveloper` int(11) NOT NULL COMMENT 'chiave esterna Developer -
relazione molti a molti',
`IDWorkSpace` int(11) NOT NULL COMMENT 'chiave esterna WorkSpace -
relazione molti a molti',
KEY `IDDeveloper` (`IDDeveloper`,`IDWorkSpace`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Tabella per relazione
molti a molti tra Developer e WorkSpac';

INSERT INTO `WorkSpaceDeveloper` (`IDDeveloper`, `IDWorkSpace`) VALUES
(1, 1),
(1, 2),
(2, 2);
//-------------------------------------------------------------------------------------------------------------


index.php
//--------------------------------------------------------------------------------------------------------------
<?php

class Developer {

public $ID;
public $Name;
public $Surname;
public $Password;

//MANY-TO-MANY
private $WorkSpaces;

public function __construct() {
$this->WorkSpaces = new Collection();
}

public function getWorkSpaces() {
return $this->WorkSpaces;
}
public function setWorkSpaces(Collection $WorkSpaces) {
$this->WorkSpaces = $WorkSpaces;
}
/*public function addWorkSpace(WorkSpace $WorkSpace) { //forse non
mettere il tipo
$WorkSpaces = $this->getWorkSpaces();
$WorkSpaces[] = $WorkSpace;
$this->setWorkSpaces($$WorkSpaces);
}*/
/*
per usarlo in index:
$post->getUsers()->add($user);
$this->con->save($post);
*/
}

class WorkSpace {

public $ID;
public $URL;

//MANY-TO-MANY
private $Developers;

public function __construct() {
$this->Developers = new Collection();
}

public function getDevelopers() {
return $this->Developers;
}
public function setDevelopers(Collection $Developers) {
$this->Developers = $Developers;
}
}

require 'outlet/Outlet.php';
Outlet::init(include 'outlet-config.php');

$outlet = Outlet::getInstance();
$outlet->createProxies();


$dev = $outlet->load('Developer', 1);
print_r( $listWorkSpace = $dev->getWorkSpaces('WHERE
{WorkSpace.StatusID} = 1') );

?>
//-------------------------------------------------------------------------------------------------------------------
outlet-config.php

<?php
return array(

'connection' => array(
'dsn' => 'mysql:host=localhost;dbname=CMS',
'username' => 'root',
'password' => 'rtmtt!10guido!',
'dialect' => 'mysql'
),

'proxies' => array(
'autoload' => true
),

'classes' => array(

'Developer' => array(
'table' => 'Developer',
'props' => array(
'ID' => array('ID', 'int', array('pk'=>true,
'autoIncrement'=>true)),
'Name'=> array('Name', 'varchar'),
'Surname'=> array('Surname', 'varchar'),
'Password'=> array('Password', 'varchar')
),
'associations' => array(
array('many-to-many', 'WorkSpace',
array('table'=>'WorkSpaceDeveloper','tableKeyLocal'=>'IDDeveloper','tableKeyForeign'=>'IDWorkSpace'))
)
),

'WorkSpace' => array(
'table' => 'WorkSpace',
'props' => array(
'ID' => array('ID', 'int', array('pk'=>true,
'autoIncrement'=>true)),
'URL'=> array('URL', 'varchar')
),
'associations' => array(
array('many-to-many', 'Developer',
array('table'=>'WorkSpaceDeveloper','tableKeyLocal'=>'IDWorkSpace','tableKeyForeign'=>'IDDeveloper'))
)
)

)
);
?>

//---------------------------------------------------------------------------------------


The collection returned is long! But without fields (URL -> a) (URL->
two) ...

Holtkamp

unread,
Aug 11, 2010, 3:49:47 PM8/11/10
to Outlet ORM
I do not completely understand the error you are trying to describe,
but I guess it has to do with mine, involving the many-to-many
relationship.

The proxy-code as generated by the OutletProxyGenerator seems to be
buggy.

Suppose:

Developer <-- many-to-many --> Workspace

$dao = new Dao_Outlet_Developer(); //DAO used to get developer
instance already in the database
//Try to load developer with primary key '1', on success, this is a
Developer_OutletProxy class
if($developer = $dao->load(1)){
//Add a new workspace to the developer
$developer->addWorkspace(new Workspace());
//Check how many workspaces the developer has
echo count($developer->workspaces); //Returns '1'

//Using the getter, this fails
$workspaces = $developer->getWorkspaces();
echo count($workspaces); //Returns '0';

//Now the property 'workspaces' of class Developer is reset as well
echo count($developer->workspaces); //Returns '0'
}

This is caused by the fact that the getter proxy code in
Developer_OutletProxy::getWorkspaces() checks whether an instanceOf
OutletCollection is returned. If not (which applies in this case) a
query is performed to lookup the workspaces in the database. However,
the added workspace object, is not yet saved in the database, so the
query results in an empty OutletCollection, which is used to fill the
Developer->workspaces property, and by doing that resets it.

Summary: when in a many-to-many relationship an object X is already
available in the database (and therefore becomes a proxy when loaded)
and an object Y (which is not in the database) is added, this is reset
when invoking the getter, has the collection of objects Y is not
registered as a OutletCollection.

Can somebody confirm that this does not work yet with many-to-many
relationships?

Holtkamp

unread,
Aug 11, 2010, 4:25:27 PM8/11/10
to Outlet ORM
My problems seemed to originate in the fact that I created my own
'addWorkspace()' function and this did not contain some code like

$this->getWorkspaces()->add($workspace);

However, now my problem is that in the many-to-many relation, I am
able to add a single entry of a workspace to the same developer twice,
while it should detect that the relation already exist in the coupling
table, right?

Now this is possible:
$developer1->workspaces(4){
- workspace1
- workspace1
- workspace1
- workspace2
}

while I expected:


$developer1->workspaces(2){
- workspace1
- workspace2
}


Suggestions?
Reply all
Reply to author
Forward
0 new messages