Accessors (Getter) & Mutators (Setter) On a Pivot Table in Laravel

后端 未结 3 672
南笙
南笙 2021-02-08 16:24

I have a pivot table that connects users to workspaces. On the pivot table, I also have a column for role, which defines the users role for that workspace. Can I provide Accesso

3条回答
  •  悲&欢浪女
    2021-02-08 16:41

    If all you need to do is access additional fields on the pivot table, you just need to use the withPivot() method on the relationship definition:

    class User extends Model {
        public function workspaces() {
            return $this->belongsToMany('App\Models\Workspace')->withPivot('role');
        }
    }
    
    class Workspace extends Model {
        public function users() {
            return $this->belongsToMany('App\Models\User')->withPivot('role');
        }
    }
    

    Now your role field will be available on the pivot table:

    $user = User::first();
    
    // get data
    foreach($user->workspaces as $workspace) {
        var_dump($workspace->pivot->role);
    }
    
    // set data
    $workspaceId = $user->workspaces->first()->id;
    $user->workspaces()->updateExistingPivot($workspaceId, ['role' => 'new role value']);
    

    If you really need to create accessors/mutators for your pivot table, you will need to create a custom pivot table class. I have not done this before, so I don't know if this will actually work, but it looks like you would do this:

    Create a new pivot class that contains your accessors/mutators. This class should extend the default Pivot class. This new class is the class that is going to get instantiated when User or Workspace creates a Pivot model instance.

    namespace App\Models;
    use Illuminate\Database\Eloquent\Relations\Pivot;
    class UserWorkspacePivot extends Pivot {
        getRoleAttribute() {
            ...
        }
        setRoleAttribute() {
            ...
        }
    }
    

    Now, update your User and Workspace models to create this new pivot table class, instead of the default one. This is done by overriding the newPivot() method provided by the Model class. You want to override this method so that you create an instance of your new UserWorkspacePivot class, instead of the default Pivot class.

    class User extends Model {
        // normal many-to-many relationship to workspaces
        public function workspaces() {
            // don't forget to add in additional fields using withPivot()
            return $this->belongsToMany('App\Models\Workspace')->withPivot('role');
        }
    
        // method override to instantiate custom pivot class
        public function newPivot(Model $parent, array $attributes, $table, $exists) {
            return new UserWorkspacePivot($parent, $attributes, $table, $exists);
        }
    }
    
    class Workspace extends Model {
        // normal many-to-many relationship to users
        public function users() {
            // don't forget to add in additional fields using withPivot()
            return $this->belongsToMany('App\Models\User')->withPivot('role');
        }
    
        // method override to instantiate custom pivot class
        public function newPivot(Model $parent, array $attributes, $table, $exists) {
            return new UserWorkspacePivot($parent, $attributes, $table, $exists);
        }
    }
    

提交回复
热议问题