-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[5.8] Pivot models provided by using() should use model methods for write operations #27571
[5.8] Pivot models provided by using() should use model methods for write operations #27571
Conversation
0fa7a3f
to
f981962
Compare
f981962
to
5d8c183
Compare
src/Illuminate/Database/Eloquent/Relations/Concerns/AsPivot.php
Outdated
Show resolved
Hide resolved
src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php
Show resolved
Hide resolved
src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php
Show resolved
Hide resolved
Seems like the clock is ticking on 5.8 😄 , is there anything more I can do to chauffeur this along? I think many might find this PR useful for similar situations to ours: needing a comprehensive way to audit changes (ie: audit trails, audit logging) to data that flows through Eloquent (including changes to pivot/junction tables). Thanks again! |
Thinking through this. Is there any implication to setting that My initial thinking is "no" since we were never really using the custom models when performing any insert / update / delete operations on Pivots. If the user iterated over their pivot models to update some values and called |
It seems the main breaking change with this PR is if people are using a custom pivot model and were also using an incrementing primary key on that model (I believe Laravel Nova itself does this actually - nevermind, it doesn't), they would need to update their custom pivot models to set Are there any other breaking changes here? |
It is entirely possible that change can be backed out... I could write a test to capture the scenario of "someone extended a pivot, is using() it, and it has primary key / autoinc instead of a compound primary key" (which is what Laravel generally wants to you have, pivots without id's). Separately, (I read your comment in laravel/ideas that basically said Eloquent was going to move towards using Pivot (Eloquent save/delete) methods anyway, instead of crafting the SQL to run the write operations with). laravel/ideas#953 (comment) That would mean someone who wanted the Pivot to use its own save/delete might write code that looks like this: namespace App\Models\Pivots;
use Illuminate\Database\Eloquent\Relations\Pivot;
class FooBar extends Pivot
{
public $usePivotSaveDelete = true;
} Then perhaps this becomes the default in 6.0? |
But, is that the only breaking change on this PR that you are aware of? |
Eh, there is another breaking change that may make me back this out for now... it's basically impossible to do a batch detach now when using a custom pivot model unless I'm mistaken. In a 5.8 application I have, I was doing this: My tests began failing after this PR and it's because obviously I can't chain query conditions on a detach anymore when using a custom pivot model. |
Eh, disregard previous code example... but I do wonder if there is a problem here when using |
Just observed this exact behaviour in our app. Our app can detach // This would ignore the context_id
$user->roles()->wherePivot('context_id', 'some-id')
->detach('some-role-id');
// This is the workaround
$user->roles()->wherePivot('context_id', 'some-id')
->wherePivot('role_id', 'some-role-id')
->detach(); |
@erikgaal please open an issue if this PR caused a bug. |
Hello, it seems that since this PR, sync is taking into account the soft delete on pivot models. But the soft delete is not taken into account when reading data from pivot models, they still appear, Thanks. |
@lk77 please open up a new issue with a detailed explanation what you're experiencing. Fill out the issue template as well please. |
There are so many issues with this PR, I think we should consider reverting or moving it to 5.9. |
@staudenmeir what does "so many issues" mean? Specifically how many do you think. Can you list them so we can determine if should fix them or revert? /cc @ralphschindler |
@ralphschindler are you able to help us with any of these? |
I don't believe #28407 is a bug. Also #28025 isn't actually a bug, not sure why you shared it as a bug @staudenmeir. |
@staudenmeir @taylorotwell @themsaid Hello, I tried to detach all elements attached to the model, but with no effect. I have User and Group model connected with belongsToMany relation, in the User model I have groups method:
In the Pivot GroupUser class I have a boot static method for listening to events:
And code, which I call:
My question is, do you in the short future make it working without adding any parameter to the detach() method? Problem is with deleting event for the Pivot class which is not called when you don't put any parameter to the detach() method. Sync not working too. |
Hi ralphschindler, i have almost the same situation here . I'm right now working on a project where i want to implement a 3-Air relationship ( Student , Exam, Subject) linking these tree tables, give us a Fourth table 'Mark'. Now what i want the user (Teacher), after navigating to a particular subject and choosing an exam, is being able to enter each student mark and by saving it these marks, it get to be stored in the appropriate table which is 'Mark' , knowing this table is referenced by (Subj_id, Exam_id, Student_id), please give me some advice on how apprehending the issue and if using a 'View Model' based view will help solving the problem |
Pivot::fromAttributes() instead of new Pivot(): laravel/framework@06f01cf & laravel/framework@4b30aad (protected) Pivot()->parent -> (public) Pivot()->pivotParent: laravel/framework@29a181f & laravel/framework@22c3c02 $otherKey -> $relatedKey: laravel/framework@d2a7777 Added fromRawAttributes() method to Pivot: laravel/framework@f356419 Various improvements to setKeysForSaveQuery(): laravel/framework@8d82618, laravel/framework@e9f37ed Fire model events when deleting Pivot models: laravel/framework#27571 Fixed Pivot serialization: laravel/framework@b52d314 & laravel/framework#31956
Overview
The driving use case behind this PR is to allow Pivot tables/classes/models to be able to trigger model events, which are currently not possible since InteractsWithPivotTable does not go through the Eloquent model.
Changes and tests have been provided.
Details
This PR adds additional support to
InteractsWithPivotTable
(used byRelations\BelongsToMany|MorphToMany
) such that write operations to a pivot table (specifically:attach
,detach
,updateExistingPivot
) will use the defined$this->belongsToMany()->using(MyPivot::class)
when performing these operations. By using the Pivot (throughAsPivot
trait methods) as an eloquent model, you gain the ability to utilize the eloquent lifecycle events when Pivot's are saved/deleted.(Sidenote: I believe there are other use cases for supporting Pivot tables at true Models, I feel like there is a use case for treating Pivot's as first class Models inside Nova.)
Example
In a situation where there exist a
Category
,Post
, and aPivots\CategoryPost
inside an application:A sync method might look like, and its output:
Inspiration & Research
https://github.com/fico7489/laravel-pivot
https://gitlab.com/altek/eventually/
https://github.com/spatie/laravel-activitylog
Laravel Issue: #8452
https://medium.com/@codebyjeff/custom-pivot-table-models-or-choosing-the-right-technique-in-laravel-fe435ce4e27e
https://github.com/signifly/laravel-pivot-events
https://stackoverflow.com/questions/46358388/laravel-5-5-events-not-fired-on-pivot