We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Identical data POSTed, different behaviour

I have a form being submitted via ajax. In response to that data being submitted, my model actively deletes all associated records, then assigns new records to be saved. This process is paraphrased below:

Controller

$this->db->begin();
$TCA = TCA::findFirst(...):
$TCA->AGPA->delete();

$new_agpa = [
    new AGPA(...),
    new AGPA(...)
];
$TCA->AGPA = $new_agpa;
$TCA->save();
$this->db->commit();

For reasons unknown to me, I can submit identical POST data 2 times in a row, and the 1st POST can result in no new AGPA records being created, but the second POST will properly delete old records and create new ones. Or vice versa. Or not - sometimes the behaviour is the same.

The POST data is identical, so the code path should be the same too. I'm at a loss as to why or how there is EVER a time where new AGPA records aren't added.

edited Dec '18

Do you have some security stuff - starting with browser extensions, AV software, and primarily some WAF at server side?

Test with plain cURL from command line or with POSTman or so. Also track relevant logs on the server.

Perhaps something's wrong with the model / DB side of things? As you do state POST is being fired each time and server accepts it? But only your part of the code does not execute.

Thanks for the response.

This "TCA" model is 1 new part of a system that has been working for over a year, and in production for 6 months. It runs on a framework that does a lot of the heavy lifting - so I doubt there's any problem client-side or with a firewall. It's also cross-browser problem.

Thanks for the tip about POSTman - it helps test this sort of thing. Unfortunately (or perhaps fortunately), the problem still exists when POSTing from POSTman.

It's got to be a model issue...somehow. I have the relationship between TCA and AGPA (which I have renamed to AGPACourse) set up like this:

$this->hasMany('id','Model\Interaction\TCA\AGPACourse','tca_id',['alias'=>'AGPACourses']);

And I set

$TCA->AGPACourses = [an array of AGPACourse objects]

But when I do a deep toArray() of $TCA, I get this:

Array
(
    [id] => 8
    [interaction_id] => 431
    [interim_program] => aaa
    [interim_sending_credits] => 0
    [interim_ua_credits] => 0
    [interim_agpa] => 0
    [interim_requirement_met] => N
    [interim_comments] => bbb
    [final_program] => aaa
    [final_sending_credits] => 0
    [final_ua_credits] => 0
    [final_agpa] => 0
    [final_requirement_met] => N
    [final_comments] => ccc
    [agpacourses] => Array
        (
            [0] => Array
                (
                    [id] => 
                    [tca_id] => 8
                    [type] => interim
                    [institution] => blah1
                    [term] => fall
                    [year] => 18
                    [course] => 
                    [credits] => 0
                    [grade] => 0
                    [ua_credits] => 0
                )

            [1] => Array
                (
                    [id] => 
                    [tca_id] => 8
                    [type] => final
                    [institution] => blah1
                    [term] => fall
                    [year] => 18
                    [course] => 
                    [credits] => 0
                    [grade] => 0
                    [ua_credits] => 0
                )
        )
)

the case is different - the key is agpacourses instead of AGPACourses. Perhaps this is just an artifact of toArray()?

edited Dec '18

Ok, I think I have it working.

The full chain of relations I have is this: $Interaction->TCA->AGPACourses. I mentioned this was in a framework - that framework renames TCA to Supplemental, because in lots of places I don't care what the particular model is. I've rewritten $Interaction->save() to then save the model identified as Supplemental if any fields have changed. However, if all that's changed is a related record then getChangedFields() doesn't return anything and the related models don't get added. So I need to find some generic way to determine if any related models to a model, have changed.