Conversation
Role lookups compared a polymorphic column against the configured class name, so a host that points the package at a subclass has to store that subclass name in every row. A host with rows already written under the base name, or one that registers a morph map, matches nothing and sees no workspaces and no members. The comparisons now ask the model through getMorphClass, which answers with the class name unless the host says otherwise, so what is stored today keeps working and an override or a morph map is honoured as well.
A role assignment is written through the user's own morph relation, so the user side of the member lookup holds whatever that answers. Comparing it against the configured class instead returned no members for a host that maps its user model, while the same host's inverse lookup worked. Both sides of the lookup now ask the model, and the controller uses the workspace it already holds rather than resolving the name a second time.
Releases 1.2.0.
Code Review Summary✨ Release 1.2.0. The change makes role and membership lookups resolve the polymorphic Read paths are updated consistently in The write paths in the trait still resolve the morph class from configuration rather than from the instance passed in, so a stored assignment name can still differ from the name every read path uses. 🚀 Key Improvements
📉 Regressions
🚨 Critical Issues
|
|
|
||
| if (method_exists($this, 'assignRole')) { | ||
| $this->assignRole($role, static::workspaceModel(), $workspace->id); | ||
| $this->assignRole($role, static::workspaceMorphClass(), $workspace->id); |
There was a problem hiding this comment.
joinWorkspace() receives the concrete $workspace instance, but writes context_type using the morph class of the configured model (static::workspaceMorphClass()). Every read path (Workspace::members(), Workspace::roleAssignments(), WorkspaceController) resolves context_type from $workspace->getMorphClass(). When the configured class and the passed instance disagree (e.g. config still points at the base Workspace while a subclass instance overrides getMorphClass()), the assignment is stored under one name and looked up under another, reproducing exactly the empty-list bug this PR fixes. Resolve the morph class from the instance being joined.
| $this->assignRole($role, static::workspaceMorphClass(), $workspace->id); | |
| $this->assignRole($role, $workspace->getMorphClass(), $workspace->id); |
| if (method_exists($this, 'removeRole')) { | ||
| foreach (Role::values() as $role) { | ||
| $this->removeRole($role, static::workspaceModel(), $workspace->id); | ||
| $this->removeRole($role, static::workspaceMorphClass(), $workspace->id); |
There was a problem hiding this comment.
Same inconsistency as joinWorkspace(): leaveWorkspace() deletes role assignments using the configured model's morph class instead of the morph class of the $workspace instance it was handed. Removal must target the same context_type value that lookups use ($workspace->getMorphClass()), otherwise a mismatched morph class leaves the assignment in place and the user keeps appearing as a member.
| $this->removeRole($role, static::workspaceMorphClass(), $workspace->id); | |
| $this->removeRole($role, $workspace->getMorphClass(), $workspace->id); |
Releases 1.2.0.
Role lookups compare the polymorphic
context_typeagainst the model's morph class instead of the configured class name, and member lookups match the user side on the name their role assignment was stored under. A host whose subclass keeps the name its table already holds, or that registers a morph map, no longer sees empty workspace and member lists.