We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    I'm probably in too deep here, but I've defined a custom model and I'm inserting relational data in a way so that I can avoid explicitly setting primary keys (since they are just database artifacts and have nothing inherently to do with the objects being stored).

    It goes a little something like this:

    $ParentObj = $this->modx->newObject('ParentClass');
    $ParentObj->fromArray($ParentObjdata); // an array WITHOUT the primary key
    $Child = $this->modx->newObject('ChildClass');
    $Child->fromArray($ChildObjdata); // everything BUT not the specific foreign key to the parent obj
    // This triggers validation errors:
    if (!$ParentObj->addOne($Child)) {
        $validator = $Child->getValidator();
        if ($validator->validate() == false) {
            $messages = $validator->getMessages();
            foreach ($messages as $m) {
                print_r($m); 
            }
        }
    }; 
    $ParentObj->save(); // only NOW do we know the primary key
    


    However, in my schema, I'm using xPDOForeignKeyConstraint xPDOValidationRule validation rules in the Child object to make sure that the parent object exists. The problem is that it seems that the validation rule in the Child seems to executes when addOne or addMany is called and BEFORE the parent object has been saved.

    In the above example you can see that the $ParentObj isn't saved until AFTER the children objects are added. Is there any hope here? I could get the last insert id and rework it, but it does defeat the purpose of having the validation rule. Maybe it's possible to override the Validator behavior? [ed. note: Everettg_99 last edited this post 12 years, 4 months ago.]
      • 3749
      • 24,544 Posts
      Maybe I don't understand what you're doing, but it seems that you'd want to add some actual fields to the child object between lines 3 and 4 so that addOne() would succeed. I could be wrong, but I think addOne() will call the validator automatically and probably write any issues to the Error Log.

      I would extend xPDOSimpleObject, but then I prefer everything to have an 'id' field -- otherwise, I have to keep looking up the PK because I forget what it is. wink

      I'm sure you could override the validate() method in your class if you find it necessary.

        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
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        Ah, you're right -- I meant to include another "fromArray" (now added), but the point is specifically that the child data OMITS the foreign key since that must get set automatically after the parent is saved. (Once you can define your seed data truly as "real" object attributes and without the arbitrary keys handed to you by the particular database instance you're working with, things really start to pop.) I could override the save method and validate things myself (the calls to the save method should waterfall through the data structure in the correct order).

        I think this is a bug: the key relationships do get set, indicating that xPDO is correctly traversing the object relations, I just think that the validation shouldn't fire until the save method is called.
          • 3749
          • 24,544 Posts
          Looking at the xPDOObject code, validate() is called during save(), but putting this in the $scriptProperties array might avoid validation (not sure about the quotes):

          scriptProperties['xPDO::OPT_VALIDATE_ON_SAVE'] = false;


          It also looks like you might be able to register your own validator by setting $this->validator to point to your own validator object that extends xPDOValidator.

          Another thought, I think your object(s) may need to override getPrimaryKey() if they don't already.
            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
            • 22303 MODX Staff
            • 10,725 Posts
            You don't want to validate these manually. Let the cascading save() handle the appropriate save order. If it does not save the related objects, perhaps your relationships are not properly defined. In particular check the owner value of the relationships being used for the cascading save() operation. Also, I would not use xPDOForeignKeyConstraint here. I'm not even sure if that works...