No, assigning a ArrayCollection to a collection in a constructor is never necessary for the association to function but *should always be done to function well in all circumstances* (like when defining a *new Module* in your code). But when using find( ), the constructor is not used at all (because, as showed in the link Menno posted, the constructor is not called at all then).
On Saturday, 8 February 2014 11:50:00 UTC+1, Parsifal wrote: > > Thanks for help. I was doing a query with WHERE clause to get only modules > with status ON, then I was creating my own foreach to assign value-pairs! > So this is why the constructor was not necessary? The constructor is > necessary only when using the way you gave to find them and assign > value-pairs? > در 2014 2 8 11:35، "Herman Peeren" <[email protected] <javascript:>> > نوشت: > >> Thank you. Now it is clear to me. I was right about the use of a name in >> singular for your Module-entity, I was wrong about supposing the ManyToOne >> relation with ModuleConfig should be the other way around. You are using an >> EAV-table ('prefix_modules_config') to flexibly add parameters to modules >> (table: 'prefix_modules'). >> >> Essential for understanding ORM: an Entity is a *single *"thing"! *Entities >> are mapped to table-ROWS, not to tables*. >> >> Let's build a model. You have 2 tables. We define 2 entities. I look at >> what the ROWS mean, not the tables: >> >> - a *Module*. It has a label (short name), a status and a collection >> of parameters (different per module) >> - a *ModuleParameter*. This is an attribute-value-pair for a specific >> module >> >> >> You could name the collection of ModuleParameters: $moduleparameters. But >> you already have a nice name for it: $moduleConfig (it is the configuration >> for 1 module, so I would keep 'module' singular here). This is one of those >> cases where I like it to have a dedicated, singular name for a collection: >> because that name gives some information about what the collection is. >> Naming is important in modeling: it gives better code, that is easier to >> understand and maintain. >> >> Now our two entities look like this: >> >> *Module *(table: 'prefix_modules'), with fields: >> >> - $label (=id; maps to the 'module'-column) >> - $status (with values ON and OFF; maps to 'status'-column) >> - $moduleConfig: a collection of ModuleParameters for this Module; >> ManyToOne-association to ModuleParameter joined on 'module'-column in >> both >> tables) >> >> >> *ModuleParameter* (table: 'prefix_modules_config'), with fields: >> >> - $module_label (id, part of the composite primary key; maps to >> 'module'-column) >> - $name (id, part of the composite primary key; maps to >> 'variable'-column) >> - $value (maps to 'value'-column) >> - $module (not necessary; only if you want to make the >> ManyToOne-association bidirectional; >> ManyToOne-association to Module joined on >> 'module'-column in both tables) >> >> >> You see I took the columns module + variable as primary key of the >> prefix_modules_config-table. But in your first code-example of yesterday >> you also had an id-column. That should not be necessary anymore in >> Doctrine2 since 2010, when this was resolved: >> http://docs.doctrine-project.org/en/2.0.x/reference/limitations-and-known-issues.html#foreign-keys-as-identifiers >> See http://www.doctrine-project.org/jira/browse/DDC-117 >> However, I often still use an extra id-field, especially when a value of >> a primary-key-field might possibly change (in your case for instance when >> the name of a module-parameter would be changed). >> >> With the above model (and some additional getters and setters) we can do >> things like: >> >> - $module = $em->find('Entities\Module', 'idev_aff'); // gives the >> idev_aff module >> - $module->addParameter($parameterName, $parameterValue); // adds a >> attribute-value-pair to this module's $moduleConfig >> - // loop through the parameters of this module >> echo 'parameters for module ' . $module->label . ':<br />'; >> foreach ($module->getModuleConfig() as $parameter) { >> echo $parameter->name . ': ' . $parameter->value . '<br />'; >> } >> >> >> Of course there are many other ways to model this, but this is how I >> would do it. I hope to have made clear what the difference is between >> thinking in objects or in tables. With ORM we are mapping two different >> "worlds", two different paradigms. Many of the problems with ORM come from >> applying the relational paradigm in the object world. >> >> *- Herman* >> >> On Friday, 7 February 2014 23:19:40 UTC+1, Parsifal wrote: >>> >>> Actually I want to allow my users to connect my product with 3rdparty >>> affiliate programs. We have 2 affiliate programs around: iDev and JAM >>> As stated in their manuals, some parameters should be passed to them >>> from my product and values of these parameters are up to my end-user >>> who uses my product. for example JAM affiliate product requires >>> username/password passed to them via cURL from my product, and this >>> username/password should be set by my end-user in database. iDev >>> requires some other parameters. >>> So in my modules table I have this coloumn: >>> prefix_modules >>> -------------------------- >>> | module | status | >>> -------------------------- >>> values in this table are this: >>> | idev_aff | 0 | >>> | jam_aff | 0 | >>> >>> so the values of module coloumn are unique. and 0/1 for status means >>> turn on/off this module or end-user wants or doesn't want to connect >>> my product with that 3rdparty affiliate product. >>> >>> then in prefix_modules_config coloumns are: >>> ------------------------------------ >>> | module | variable | value | >>> ------------------------------------ >>> and values of these coloumns are: >>> ------------------------------------ >>> | idev_aff | idev_pass | password goes here >>> | idev_aff | idev_user | username goes here >>> | jam_aff | jam_url | url goes here >>> | jam_aff | jam_key | key goes here >>> >>> Now my product checks if a module (e.g. iDev is turn on) then gets its >>> idev_pass and idev_user from prefix_modules_config table. >>> these two tables are joined by the value of "module" coloumn. and ONLY >>> the "value" and "status" coloumns are editable for my end-user. So >>> prefix_modules is OneToMany to prefix_modules_config. >>> Now my entities in previous email are clear? if I did some upercase >>> mistakes please advice and advice about constructor. >>> >>> >>> >>> On Sat, Feb 8, 2014 at 1:23 AM, Herman Peeren <[email protected]> >>> wrote: >>> > @Parsival/Nima: Menno didn't say it was not good to use a constructor, >>> but >>> > pointed to the explanation why that constructor was not called. It is >>> still >>> > good to have it, for if you make a new Modules (or whatever you will >>> > eventually call this entity) yourself, you want to add a ModulesConfig >>> to >>> > that Moduels-entity. I still think you mean it the other way around, >>> but >>> > please explain in English what you want to model, what the meaning is >>> of >>> > your modules and modulesConfig etc. >>> > >>> > On Friday, 7 February 2014 22:41:04 UTC+1, Parsifal wrote: >>> >> >>> >> Menno, >>> >> >>> >> Actually I was reading here that says a OneToMany must have a >>> >> constructor to instantiate ArrayCollection(); >>> >> >>> >> http://docs.doctrine-project.org/en/latest/reference/ >>> association-mapping.html >>> >> What else I have to do? I don't understand what I missed? >>> >> >>> >> >>> >> >>> >> On Sat, Feb 8, 2014 at 1:03 AM, Herman Peeren <[email protected]> >>> wrote: >>> >> > Yes, that is the explanation of why that constructor is not >>> invoked. >>> >> > Thank >>> >> > you, Menno! Stupid that I hadn't thought of that... But still I >>> have my >>> >> > doubts about the modelling of the Entities here. >>> >> > >>> >> > On Friday, 7 February 2014 22:25:11 UTC+1, Holtkamp wrote: >>> >> >> >>> >> >> Ok, sorry, I can't withstand: >>> >> >> http://lmgtfy.com/?q=doctrine+entity+constructor >>> >> >> >>> >> >> and: >>> >> >> >>> >> >> http://docs.doctrine-project.org/en/latest/reference/ >>> architecture.html#entities, >>> >> >> states: >>> >> >> >>> >> >> The constructor of an entity is only ever invoked when you >>> construct a >>> >> >> new >>> >> >> instance with the new keyword. Doctrine never calls entity >>> >> >> constructors, >>> >> >> thus you are free to use them as you wish and even have it require >>> >> >> arguments >>> >> >> of any type. >>> >> >> >>> >> >> Please, a lot of people (myself included), spend quite some time >>> to >>> >> >> read >>> >> >> the documentation (written by volunteers, respect it). Yes, it is >>> a lot >>> >> >> and >>> >> >> it might take some hours / days, but is seems you are persistent >>> enough >>> >> >> to >>> >> >> not quit before you got what you want ;). So before posting a >>> question >>> >> >> again, count to 100 out loud! >>> >> >> >>> >> >> Cheers! >>> >> >> >>> >> >> >>> >> >> On 7 February 2014 22:19, Menno Holtkamp <[email protected]> >>> wrote: >>> >> >>> >>> >> >>> This might have something to do with the Entity proxy >>> intercepting the >>> >> >>> initialization (in combination with lazy loading?). I believe >>> Marco >>> >> >>> Piveta >>> >> >>> AKA Ocramius wrote a lot about the subject. Google for it and/or >>> dive >>> >> >>> in the >>> >> >>> source code. >>> >> >>> >>> >> >>> But, you can also trust on the force to always be with you, >>> right? >>> >> >>> >>> >> >>> Cheers >>> >> >>> >>> >> >>> On Feb 7, 2014 9:35 PM, "Nima Sadjadi" <[email protected]> >>> wrote: >>> >> >>>> >>> >> >>>> Herman, >>> >> >>>> Here is the info you asked me this morning, correcting uppercase >>> >> >>>> things etc. it returns expected data the only odd thing is that >>> >> >>>> print("blah") in constructor is not working so the this is not >>> called >>> >> >>>> but still works! any idea? >>> >> >>>> >>> >> >>>> <?php >>> >> >>>> // Modules.php >>> >> >>>> namespace Entities; >>> >> >>>> use Doctrine\ORM\Mapping\ClassMetadata; >>> >> >>>> use Doctrine\ORM\Mapping\ClassMetadataInfo; >>> >> >>>> use Doctrine\Common\Collections\ArrayCollection; >>> >> >>>> class Modules { >>> >> >>>> private $module; >>> >> >>>> private $status; >>> >> >>>> private $modulesConfig; >>> >> >>>> public function __construct() { >>> >> >>>> $this->modulesConfig = new ArrayCollection(); >>> >> >>>> print("a"); >>> >> >>>> var_dump($this->modulesConfig); >>> >> >>>> } >>> >> >>>> public static function loadMetadata(ClassMetadata $metadata) >>> { >>> >> >>>> // here goes $metadata->mapField array I did generate with >>> CLI >>> >> >>>> // coloumns in this table: module, status >>> >> >>>> // join coloumns with that other table: module=>module >>> >> >>>> $metadata->mapOneToMany(array( 'fieldName' => >>> 'modulesConfig', >>> >> >>>> 'targetEntity' => >>> >> >>>> 'Entities\\ModulesConfig', >>> >> >>>> 'mappedBy' => 'modules', >>> >> >>>> 'joinColumns' => array( 0 => >>> array( >>> >> >>>> 'name' => 'module', >>> >> >>>> >>> >> >>>> 'referencedColumnName' => 'module', >>> >> >>>> >>> >> >>>> 'nullable' => true, >>> >> >>>> >>> >> >>>> 'columnDefinition' => NULL, >>> >> >>>> ), ) >>> >> >>>> >>> >> >>>> )); >>> >> >>>> } >>> >> >>>> } >>> >> >>>> == >>> >> >>>> <?php >>> >> >>>> // ModulesConfig.php >>> >> >>>> namespace Entities; >>> >> >>>> use Doctrine\ORM\Mapping\ClassMetadata; >>> >> >>>> use Doctrine\ORM\Mapping\ClassMetadataInfo; >>> >> >>>> class ModulesConfig { >>> >> >>>> private $id; >>> >> >>>> private $module; >>> >> >>>> private $variable; >>> >> >>>> private $value; >>> >> >>>> private $modules; >>> >> >>>> public static function loadMetadata(ClassMetadata $metadata) >>> { >>> >> >>>> // here goes $metadata->mapField array I did generate with >>> CLI >>> >> >>>> // coloumn in this table: id, module, variable, value >>> >> >>>> // join coloumns with that other table: module=>module >>> >> >>>> >>> >> >>>> $metadata->mapManyToOne(array( 'fieldName' => 'modules', >>> >> >>>> 'targetEntity' => >>> 'Entities\\Modules', >>> >> >>>> 'inversedBy' => 'modulesConfig', >>> >> >>>> 'joinColumns' => array( 0 => >>> array( >>> >> >>>> 'name' => 'module', >>> >> >>>> >>> >> >>>> 'referencedColumnName' => 'module', >>> >> >>>> >>> >> >>>> 'nullable' => true, >>> >> >>>> >>> >> >>>> 'columnDefinition' => NULL, >>> >> >>>> ), ) >>> >> >>>> >>> >> >>>> )); >>> >> >>>> } >>> >> >>>> } >>> >> >>>> >>> >> >>>> >>> >> >>>> >>> >> >>>> >>> >> >>>> On Fri, Feb 7, 2014 at 1:38 PM, Herman Peeren < >>> [email protected]> >>> >> >>>> wrote: >>> >> >>>> > No idea what you are doing wrong without the code of the 2 >>> entities >>> >> >>>> > plus the >>> >> >>>> > calling code, query etc. >>> >> >>>> > >>> >> >>>> > On Friday, 7 February 2014 10:34:08 UTC+1, Parsifal wrote: >>> >> >>>> >> >>> >> >>>> >> In two cases below you described, the first case is the one I >>> >> >>>> >> actually >>> >> >>>> >> want to. And actually it is working fine with expected >>> result. The >>> >> >>>> >> only odd >>> >> >>>> >> thing is that print("blah") in constructor doesn't print so I >>> >> >>>> >> assume >>> >> >>>> >> the >>> >> >>>> >> constructor is not working however I am still getting correct >>> >> >>>> >> result! >>> >> >>>> >> Second >>> >> >>>> >> odd thing is that only getArrayResult returns something for >>> this >>> >> >>>> >> but >>> >> >>>> >> I get >>> >> >>>> >> error for getResult. Let's look at second problem later but >>> first >>> >> >>>> >> let's >>> >> >>>> >> check why constructor is not working however I am still >>> getting >>> >> >>>> >> correct >>> >> >>>> >> result?! Any idea? >>> >> >>>> >> >>> >> >>>> >> 1) In a Module-entity you can have multiple >>> ModuleConfig-entities >>> >> >>>> >> and >>> >> >>>> >> every ModuleConfig-entity only has 1 Module. In this case >>> you'll >>> >> >>>> >> have >>> >> >>>> >> a >>> >> >>>> >> $moduleConfigs collection in a Module on which a >>> >> >>>> >> OneToMany-relationship is >>> >> >>>> >> defined. In a ModuleConfig you then have a $module defined >>> with a >>> >> >>>> >> ManyToOne >>> >> >>>> >> relation. >>> >> >>>> >> 2) Or: in a Module-entity you can only have 1 >>> ModuleConfig-entity, >>> >> >>>> >> but a >>> >> >>>> >> ModuleConfig-entity can be associated with multiple >>> >> >>>> >> Module-entities. >>> >> >>>> >> In >>> >> >>>> >> that case you'll have a $moduleConfig propery in a Module on >>> which >>> >> >>>> >> a >>> >> >>>> >> ManyToOne-relationship is defined. In a ModuleConfig you then >>> have >>> >> >>>> >> a >>> >> >>>> >> $modules collection defined with a OneToMany relation. >>> >> >>>> > >>> >> >>>> > -- >>> >> >>>> > You received this message because you are subscribed to the >>> Google >>> >> >>>> > Groups >>> >> >>>> > "doctrine-user" group. >>> >> >>>> > To unsubscribe from this group and stop receiving emails from >>> it, >>> >> >>>> > send >>> >> >>>> > an >>> >> >>>> > email to [email protected]. >>> >> >>>> > To post to this group, send email to >>> [email protected]. >>> >> >>>> >>> >> >>>> > Visit this group at http://groups.google.com/ >>> group/doctrine-user. >>> >> >>>> > For more options, visit https://groups.google.com/ >>> groups/opt_out. >>> >> >>>> >>> >> >>>> -- >>> >> >>>> You received this message because you are subscribed to the >>> Google >>> >> >>>> Groups "doctrine-user" group. >>> >> >>>> To unsubscribe from this group and stop receiving emails from >>> it, >>> >> >>>> send >>> >> >>>> an email to [email protected]. >>> >> >>>> To post to this group, send email to [email protected]. >>> >>> >> >>>> >>> >> >>>> Visit this group at http://groups.google.com/group/doctrine-user. >>> >>> >> >>>> For more options, visit https://groups.google.com/groups/opt_out. >>> >>> >> >> >>> >> >> >>> >> > -- >>> >> > You received this message because you are subscribed to the Google >>> >> > Groups >>> >> > "doctrine-user" group. >>> >> > To unsubscribe from this group and stop receiving emails from it, >>> send >>> >> > an >>> >> > email to [email protected]. >>> >> > To post to this group, send email to [email protected]. >>> >> > Visit this group at http://groups.google.com/group/doctrine-user. >>> >> > For more options, visit https://groups.google.com/groups/opt_out. >>> > >>> > -- >>> > You received this message because you are subscribed to the Google >>> Groups >>> > "doctrine-user" group. >>> > To unsubscribe from this group and stop receiving emails from it, send >>> an >>> > email to [email protected]. >>> > To post to this group, send email to [email protected]. >>> > Visit this group at http://groups.google.com/group/doctrine-user. >>> > For more options, visit https://groups.google.com/groups/opt_out. >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "doctrine-user" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> To post to this group, send email to [email protected]<javascript:> >> . >> Visit this group at http://groups.google.com/group/doctrine-user. >> For more options, visit https://groups.google.com/groups/opt_out. >> > -- You received this message because you are subscribed to the Google Groups "doctrine-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/doctrine-user. For more options, visit https://groups.google.com/groups/opt_out.
