We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 50497
    • 30 Posts
    I'm having a difficult time wrapping my head around xPDO relationships. I've read as much documentation as I can, but it's just not real clear. Especially, in regards to MIGx. Let me see if I can't paint a simple picture.

    Two tables: One is Location and One is State

    The location table will hold all the address information. Street, City, State and Zip. Traditionally, I would create a separate table to house state information in order to avoid duplicate lengthy entries in the table. I'm assuming this is where xPDO relationships would play a role?

    To this point when I've used MIGx I've only created one package per table. Am I going about this all wrong? Should one package contain all my tables for a particular project? Based on the example above would I create both the location and state tables within a package called location? Would I define the relationship between the two tables in my schema?

    I would appreciate any help you may be willing to provide. I just need to get a better grasp of this.
      • 3749
      • 24,544 Posts
      Typically, you'd do this with a single package. In the schema, you'd specify both objects/tables and create aliases that let you do this:

      $state = $location->getOne('State');


      and this:

      $locations = $state->getMany('Locations');


      This page doesn't say much about custom tables, but you might still find is useful: http://bobsguides.com/revolution-objects.html.

      Once you set up your package and create the class and map files, your objects work just like the MODX objects do.

      I haven't used MIGX for this, so I can't help you with that part of it.

        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 4172
        • 5,888 Posts
        Usually, you put all tables, which are related to your project into one package.
          -------------------------------

          you can buy me a beer, if you like MIGX

          http://webcmsolutions.de/migx.html

          Thanks!
          • 50497
          • 30 Posts
          Ok, well that makes it a little clearer. Based on my example above I've put together a schema. I just want to make sure I'm understanding.

          <?xml version="1.0" encoding="UTF-8"?>
              <model package="company_profile"
              baseClass="xPDOObject"
              platform="mysql"
              defaultEngine="MyISAM"
              version="1.1">
                  <object class="state" table="states" extends="xPDOSimpleObject">
                      <field key="stateName" dbtype="varchar" precision="50" phptype="string" null="false" default="" />
                      <field key="stateAbbreviation" dbtype="varchar" precision="2" phptype="string" null="false" default="" />
                  </object>
                  <object class="address" table="addresses" extends="xPDOSimpleObject">
                      <field key="FK_StateId" dbtype="int" precision="10" phptype="integer" null="false" default="" />
                      <field key="street" dbtype="varchar" precision="255" phptype="string" null="true" default="" />
                      <field key="city" dbtype="varchar" precision="255" phptype="string" null="true" default="" />
                      <field key="zip" dbtype="varchar" precision="20" phptype="string" null="true" default="" />
                      <aggregate alias="states" class="state" local="id" foreign="FK_StateId" cardinality="one" owner="foreign" />
                  </object>
          </model>


          This schema should create two tables states and addresses. The state table will contain 3 fields id, stateName, stateAbbreviation. The address table contains basic address info with a foreign key FK_StateId which will hold the id of the state.

          This line is what creates the relationship?
          <aggregate alias="states" class="state" local="id" foreign="FK_StateId" cardinality="one" owner="foreign" />


          I'm assuming this would only be needed in the addresses table? I understand the class is going to reference the class of the state table, the local id is the unique id of the state table, and the foreign field is going to reference the foreign id in the address table? I don't really understand what alias is and what it relates to.

          Thanks for all your help.
            • 4172
            • 5,888 Posts
            <?xml version="1.0" encoding="UTF-8"?>
                <model package="companyprofiles" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
                    <object class="cpState" table="cp_states" extends="xPDOSimpleObject">
                        <field key="name" dbtype="varchar" precision="50" phptype="string" null="false" default="" />
                        <field key="abbreviation" dbtype="varchar" precision="2" phptype="string" null="false" default="" />
                        <composite alias="Addresses" class="cpAddress" local="id" foreign="state_id" cardinality="many" owner="local" />
                    </object>
                    <object class="cpAddress" table="cp_addresses" extends="xPDOSimpleObject">
                        <field key="state_id" dbtype="int" precision="10" phptype="integer" null="false" default="" />
                        <field key="street" dbtype="varchar" precision="255" phptype="string" null="true" default="" />
                        <field key="city" dbtype="varchar" precision="255" phptype="string" null="true" default="" />
                        <field key="zip" dbtype="varchar" precision="20" phptype="string" null="true" default="" />
                        <aggregate alias="State" class="cpState" local="state_id" foreign="id" cardinality="one" owner="foreign" />
                    </object>
                </model>
            


            This is, how I would name things:

            package-name all lowercase without any special-characters
            field-names all lowercase, only underscores as special-characters
            Classnames camel-case with prefix, which makes the names more unique
            tablenames all lowercase, only underscores as special-characters

            The alias of the relation is used for example in joins and in getMany or getOne - methods,
            Examples, to get the idea:

            if ($state = $modx->getObject('cpState',$state_id)){
                if ($addresscollection = $state->getMany('Addresses'){
                    foreach ($addresscollection as $object){
                        $rows[] = $object->toArray();
                    }
                } 
            }


            if ($address = $modx->getObject('cpAddress',$address_id)){
                if ($stateObject = $address->getOne('State'){
                    $row = $stateObject->toArray();
                } 
            }
            
              -------------------------------

              you can buy me a beer, if you like MIGX

              http://webcmsolutions.de/migx.html

              Thanks!
              • 50497
              • 30 Posts
              Bruno,
              Again thanks for all your help with my questions as of late.

              I'm wondering is it possible to create a relationship between whatever table Modx is using for the user login information and custom another table. So for instance if I wanted the link the modx-user-id to a custom table could I create that relationship within my xPDO schema?

              I hope that makes sense. I'm hoping to make a custom table where the foreign key value has a relationship to $modx->user->get('id') where ever that is actually pulled from.
                • 4172
                • 5,888 Posts
                  -------------------------------

                  you can buy me a beer, if you like MIGX

                  http://webcmsolutions.de/migx.html

                  Thanks!