We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 4172
    • 5,888 Posts
    As soon, as you have many to many relations (a reseller->many products, a product -> many resellers), it doesn't make any sense, having direct relations between the two related tables.
    You will allways need a connection-table(ResellerProduct), like you did.

    How should many to many - relations work without that connection-table?
      -------------------------------

      you can buy me a beer, if you like MIGX

      http://webcmsolutions.de/migx.html

      Thanks!
      • 4172
      • 5,888 Posts
      Quote from: dmeganoski at Jul 29, 2016, 02:31 PM
      What I mean to say is, Isn't there a way to define the relation so that I could do something like:

      $reseller = $modx->getObject('Reseller', 1);
      
      $res_products = $reseller->getMany('Products');


      exactly this is possible, of course, but only if you have a one to many-relation.

      maybe, you are looking for getObjectGraph
      https://rtfm.modx.com/xpdo/2.x/class-reference/xpdo/xpdo.getobjectgraph
        -------------------------------

        you can buy me a beer, if you like MIGX

        http://webcmsolutions.de/migx.html

        Thanks!
        • 52563
        • 12 Posts
        Well, the connection table is still required. It would just more transparent to me working with the models, handled silently by the ORM. With the previous example, to define the relation in eloquent, you would add one simple function to the model.

        Reseller model:

        public function products() {
            return $this->hasMany('Product', 'reseller_products', 'reseller_id', 'product_id');
        }


        Product Model:

        public function resellers() {
            return $this->hasMany('Reseller', 'reseller_products', 'product_id', 'reseller_id');
        }


        And then retrieving / adding new items would be as simple as:

        $reseller = Reseller::find(1);
        
        $res_products = $reseller->products;
        
        $product = new Product();
        
        $product->name = 'demo';
        
        $reseller->products->attach($product);


        Perhaps I am just a little spoiled with the convenience. smiley It is not that big of a deal that I have to run an extra query to get the second table, or have to create the pivot manually. I just thought there would be something similar for xpdo.

        For example,

        <?xml version="1.0" encoding="UTF-8"?>
        <model package="resellers" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.0">
        
            <object class="Reseller" table="resellers" extends="xPDOSimpleObject">
                <field key="id" dbtype="int" precision="11" phptype="integer" null="false" index="pk"  generated="native" />
                <index alias="PRIMARY" name="PRIMARY" primary="true" unique="true">
                    <column key="id" collation="A" null="false" />
                </index>
        
                <otherrelation alias="Products" class="Product" local="reseller_id" foreign="product_id" pivot="ResellerProduct" cardinality="many" owner="local"/>
        
            </object>
        
            <object class="Product" table="products" extends="xPDOSimpleObject">
                <field key="id" dbtype="int" precision="11" phptype="integer" null="false" index="pk"  generated="native" />
                <index alias="PRIMARY" name="PRIMARY" primary="true" unique="true">
                    <column key="id" collation="A" null="false" />
                </index>
        
                <otherrelation alias="Resellers" class="Reseller" local="product_id" foreign="reseller_id" pivot="ResellerProduct" cardinality="many" owner="local"/>
        
            </object>
        
            <object class="ResellerProduct" table="reseller_product" extends="xPDOObject">
                <field key="id" dbtype="int" precision="11" phptype="integer" null="false" index="pk"  generated="native" />
                <index alias="PRIMARY" name="PRIMARY" primary="true" unique="true">
                    <column key="id" collation="A" null="false" />
                </index>
        
                <field key="reseller_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0"/>
                <field key="product_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0"/>
                <!-- no relation needed -->
            </object>
        </model>


        Just seen your reference to getObjectGraph. Had not seen that before, that certainly helps. smiley The performance loss of having to run multiple queries was another concern.

        Still wondering how I could nest a grid of products within my form tab, though. If you get what I am trying to achieve smiley

        (I already owe you a couple beers)
          • 52563
          • 12 Posts
          Sigh. I can't seem to get the 'aftergetfields' snippet to fire.

          I have added the snippet to the "Hook Snippets" settings field.

          {"aftersave":"save_reseller_users","aftergetfields":"get_reseller_users"}


          I have created a plugin which loads the Kint debugger class when modx starts up. I usually use the ddd() function in snippets to see what data I have available to me.

          The snippet seems to not be fired. Furthermore, investigating the fields.php file you referenced, putting a die() or ddd() at the beginning of the page does not seem to have an effect either. Is it not being called as well?

          I can't seem to find where this file is included to do further investigation...

          EDIT: Ahhhh... it is being fired for the individual record that is being edited, not the grid. Well, that is better than using the 'default value' field of the multi-select to populated selected.

          Still, I haven't figured out a way to get a list of usernames into the grid... is there another hook snippet event for this? [ed. note: dmeganoski last edited this post 7 years, 9 months ago.]
          • discuss.answer
            • 4172
            • 5,888 Posts
            yeah, the fields - processor runs each time, when the modal-form is called.
            For the list of usernames in the columns, use the renderchunk-renderer with a migxLoopCollection-call in the tpl-chunk-field.

            something like that in the renderChunk-tpl:

            [[migxLoopCollection?
            &packageName=`resellers`
            &classname=`ResellerUser`
            &joins=`[{"alias":"User"}]`
            &where=`{"reseller_id":"[[+id]]"}`
            &tpl=`@CODE:[[+User_username]]`
            &outputSeparator=`,`
            ]] 
              -------------------------------

              you can buy me a beer, if you like MIGX

              http://webcmsolutions.de/migx.html

              Thanks!
              • 52563
              • 12 Posts
              Ahhh, thanks a lot. That did it. I hadn't see the joins property used with that snippet. I was trying to use the 'migxGetCollectionTree' snippet, but was not having much luck.

              It will take me a while to get familiar with all of these snippets. I should go through them and read what documentation you have included in them.

              Well that solves most of my basic issues, and gives me a good base for how to build cmp's with relations. Thanks again, much appreciated.

              And I just found this thread on nested grids: https://forums.modx.com/thread/?thread=78186&page=2

              The video that nadakbar posted is exactly what I was looking for. I think we're good here. smiley

              Much appreciated. Look forward to speaking with you again.
                • 36416
                • 589 Posts
                Quote from: Bruno17 at Jul 29, 2016, 06:30 AM
                Thanks for a very helpful post @Eoler!

                Sorry for being less than helpful, I just recognized a nickname from the other forum and tried to set expectations... I believe there would be the way to model anything with your ingenious plugin, just not as clean as Eloquent + Behavoirs (Traits).
                  • 36416
                  • 589 Posts
                  Quote from: dmeganoski at Jul 29, 2016, 01:45 PM
                  Quote from: danilocuculic at Jul 29, 2016, 05:46 AM
                  You won't be happy with xPDO after using that other month-named CMS... good luck.

                  Well, I have been working with Laravel itself for a while now. I only recently ventured into October CMS, but there are many drawbacks to it. For example, the lack of multi-tenant support and the lack of separation of logic from design.

                  Multi-tenant is hard - never seen a good high-level implementation (maybe Drupal?), and low-level Laravel routing is too SAD (slow, non-RAD) for me. But you have a point.
                  What "lack of separation" - is this about a purity of programming paradigm and components are not enough? But let's not derail your great TypoCMS -> MODX conversation, ok?
                    • 52563
                    • 12 Posts
                    Yes, especially when different setups have different requirements. Sometimes the 'context' is determined by the domain, sometimes by the user. Sometimes different tenants need different databases. Sometimes several domains share a context. Sometimes you need a central database for shared data. It's hard to compensate for all of those different requirements. Modx so far has been able to do all of this without me needing to hack core files.

                    What I meant by lack of separation of design and logic is the mixture of logic in the templates. There are many companies out there who have designers who just don't understand logic and struggle with it every time they are forced to deal with it.

                    Even Modx uses placeholders and such in the resources, but the way that resources and elements are managed separates the backend and frontend development. Me and my employer both agree it is a nice system.

                    I just have to get used to some of the new design ideas that come with modx. Template Variables had me confused for a while, but I think I'm getting the jist of it now.