Closed Bug 502144 Opened 15 years ago Closed 15 years ago

model associations binding wtf

Categories

(addons.mozilla.org Graveyard :: Public Pages, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: jbalogh, Assigned: jbalogh)

References

Details

Attachments

(1 file, 1 obsolete file)

attachment 386653 [details] [diff] [review] on bug 501187 is triggering a weird model association error where bindOnly fails intermittently.  When you unbindModel, cake stores that "deleted" association in $this->__backAssociation, and resurrects it with __resetAssociations().  bindOnly calls __reset to make sure everything is there before it does its work.  When we hit the error, __backAssociation is empty but Addon->hasAndBelongsToMany only contains the Tag association.  User, Category, and Collection are getting lost somewhere along the way, so we'll never be able to bind those again.

The Tag association is new, so I'm suspecting some webmocha foul play.

            echo '<pre>';print_r($this->Addon->__backAssociation);echo '</pre><hr>';
            echo '<pre>';print_r($this->Addon->hasAndBelongsToMany);echo '</pre><hr>';
            $this->Addon->__resetAssociations();
            echo '<pre>';print_r($this->Addon->hasAndBelongsToMany);echo '</pre><hr>';
            echo '<pre>';print_r($this->Addon->__backAssociation);echo '</pre><hr>';

shows you what's going on, and I put that before bindOnly('User') in addons_controller:display
Blocks: 501187
This happens about 50% of the time I think, but I've had it work fine for 10 or
so reloads before it breaks too. :(
More print debugging (which is completely awesome, btw) shows that we have errors when getAddon *misses* the cache.
This fixes what appears to me to be a cake bug.  The functions we're looking at are __resetAssociations, bindModel and unbindModel in site/cake/libs/model/model_php5.php.

We'll use $this->hasMany as an example association, but the following applies to all of them.  

When you change unbind something in $this->hasMany, cake stores a copy of $this->hasMany in __backAssociation['hasMany'].  Good idea, now we can undo the unbinding.  But then let's say you call bindModel again, with something in hasMany.  This is a common pattern in amo, unbindFully and then rebind specific parts.

*BUT* when you bindModel, cake stores a copy of $this->hasMany in __backAssociation['hasMany'].  Yes, overwriting the original full hasMany with this pared-down version.  Then we do a query and cake calls __resetAssociations to put everything back, but we only remember the meager version of our associations.  Doh!

This patch stores all the associations at startup and never messes with that copy again.  When we want to reset we look at the pristine copy we stored and reset from there.
Attachment #386680 - Flags: review?(clouserw)
Attached patch v2Splinter Review
Turns out the associations aren't all set up in the beginning, so we need to grab our copy after initialization.
Attachment #386680 - Attachment is obsolete: true
Attachment #386687 - Flags: review?(clouserw)
Attachment #386680 - Flags: review?(clouserw)
Comment on attachment 386687 [details] [diff] [review]
v2

triple secret underscores!
Attachment #386687 - Flags: review?(clouserw) → review+
r29329
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
Product: addons.mozilla.org → addons.mozilla.org Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: