Closed weotch closed 10 years ago
I did a couple things to work around this.
Add "protected $morphType;" to MorphPivot, so that when MorphToMany newPivot calls setMorphType on the MorphPivot, the type column name doesn't get added to the attributes of the pivot model (this is where your extra morphType column is coming from).
Then to handle the value for that not being set, I added a line to MorphToMany __construct after $this->morphType is set that calls $this->withPivot($this->morphType). Now that will be there automatically.
I also noticed that all the columns were being updated (empty original). I think fixing that could help, but I think having at least the first change would still be necessary to prevent an attribute called "morphType" from getting into the pivot model (which would of course not be present in the original, so it would look dirty, so it would attempt to be saved incorrectly). Maybe bringing the actual morph class value in with the extra withPivot call wouldn't be needed, because maybe there's not actually a way that would ever change.
P.S. this was happening because I was calling ->pivot->save(). If there's another way you're supposed to update pivot models let me know, maybe that's the issue.
How has this issue has not been addressed in these two months? Perhaps a pull request will bring it to someone's attention.
Adding $morphType
as a protected object on the MorphPivot class resolves the erroneous column in the query so at minimum, that makes for a solid pull on all applicable branches.
It would be a strange use case where a morphType would change. This would imply that an object from one table representing one type was being moved to another. In the context of polymorphism, this can reasonably happen when casting inherited objects to their parent classes, etc., but in a database, this is a bit of an oddball indicative of some curious database design. The correct approach would be to insert copied data as a new model into the other table, then change the morphable object id and morphType to maintain the associated data about the relationship and drop the old object. I have trouble coming up with a specific use case for that and it sounds rather convoluted, but maybe I'm missing something there.
The empty original is certainly making for inefficient queries and this could get costly if the pivot data were large. That certainly warrants further looking into.
Given a
buildings
table and aservices
table and a pivot table that looks like:Buildings (and other models) can have Services. The Service model has this relationship:
I attempt to update the pivot column like so:
I get this exception:
There are a couple of things I've noticed here that I think are incorrect:
morphType
. I'm not sure where that column is coming from.serviceable_type
is NULL. If I update thewithPivot()
on the relationship function to includeserviceable_type
, it gets correctly set to "Building". I think the polymorphic type column should have been automatically selected$original
property of the Pivot model is an empty array. I think it should have been hydrated.