2015-03-08 20 views
7

Kullanıcıları çalışma alanlarına bağlayan bir pivot tablomuz var. Özet tablosunda, bu çalışma alanının kullanıcı rolünü tanımlayan bir rol sütunum da var. Pivot tablonun içindeki rolde Accessor (Getter) & Mutator (Setter) yöntemleri sağlayabilir miyim? Her yere bakmaya çalışıyorum, ama elimdeki pivot tablolara dair detaylar oldukça seyrek.Accessors (Getter) & Mutators (Setter) Laravel Pivot Tablosunda

Özel bir pivot modelini kurmak zorunda mıyım emin değilim? Eğer yaparsam, pivot modellerinin dokümantasyonu çok basit olduğundan bir örnek harika olurdu.

Teşekkürler.

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'); 
    } 
} 

Şimdi rolünüz alan pivot tabloda yer alacaktır: yapmanız gereken tüm Pivot masaya erişim ek alanlar ise

+0

ben elle yapmaya çalışıyorum:

Şimdi normal yerine belongsToMany senin modelleri içinde ki kullanırlar. İşte sahip olduğum şey: http://laravel.io/bin/RE2ze – ATLChris

cevap

7

, sadece ilişki tanımı withPivot() yöntemi kullanmak gerekir :

$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']); 

gerçekten erişenleri oluşturmanız gerekiyorsa/pivot tablo için mutators, özel bir pivot tablo sınıf oluşturmak gerekecektir. Bunu daha önce yapmadım, dolayısıyla bunun gerçekten işe yarayıp yaramadığını bilmiyorum, ancak bunu yapardınız gibi görünüyor:

Aksesuarı/mutatorlarınızı içeren yeni bir pivot sınıfı oluşturun. Bu sınıf varsayılan Pivot sınıfını genişletmelidir. Bu yeni sınıf, Kullanıcı veya Çalışma Alanı bir Pivot model örneği oluşturduğunda örneklenecek sınıftır.

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

Şimdi, yerine varsayılan biri, bu yeni pivot tablo sınıf oluşturmak için Kullanıcı ve Çalışma Alanı modellerini güncellemek. Bu, Model sınıfı tarafından sağlanan newPivot() yöntemini geçersiz kılarak yapılır. Bu yöntemi geçersiz kılmak, böylece varsayılan Pivot sınıfı yerine yeni UserWorkspacePivot sınıfınızın bir örneğini oluşturursunuz.

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); 
    } 
} 
+0

Detaylı yanıtınızı çok takdir ediyorum ama maalesef bu işe yaramıyor. 'GetRoleAttribute' ve 'setRoleAttribute' asla uygulanamaz. – ATLChris

+0

@ATLChris Sadece denedim bu bir test ortamı ve işe yarıyor gibi görünüyor. Mevcut kodunuzu, yapmaya çalıştığınız şeyleri, gerçekleşmeyi umduğunuz şeyi, gerçekte neler olduğunu ve aldığınız hataları kaydeder misiniz? – patricus

+1

@ATLChris bu işe yarıyor. Bu yaklaşımı kullanarak bu sorunu çözdüm. Daha fazla ayrıntı için [Laravel - Elocele'deki özel pivot modeli] makalesini okuyabilirsiniz (http://softonsofa.com/laravel-custom-pivot-model-in-eloquent/) – hhsadiq

0

Bu zor bir sorudur. Düşünebildiğim çözümler kokuyor ve daha sonra bazı sorunlara neden olabilir.

Patricus'un çalışmasını sağlamak için cevabını uzatacağım.

Patricus'un cevabı üzerine yorum yapacaktım ama açıklamak için çok fazla şey var. Onun çözümünü attach ve sync ile yapmak için bazı çirkin şeyler yapmalıyız.

Sorun

İlk önce onun çözümü ile sorunu tanımlamak edelim. Onun alıcıları ve ayarlayıcıları işe yarıyorlar, ancak otomToMany ilişkisi, sync, attach veya detach'u çalıştırırken Pivot modelini kullanmaz. Bu, bunlardan birini aradığımızda her zaman $attributes parametresi ile mutasyona uğramamış veri veritabanı sütununa konacaktır.

// This will skip the mutator on our extended Pivot class 
$user->workspaces()->attach($workspace, ['role' => 'new role value']); 

Biz sadece bunlardan birini çağırmak her zaman biz mutasyona uğramış verileri eklemek ve sadece mutasyonlu olmalıdır verilerle updateExistingPivot çağırmak için ikinci bir parametre kullanamazsınız hatırlamak deneyebilirsiniz.Yani bir attach Patricus belirtilen ne olurdu:

$user->workspaces()->attach($workspace); 
$user->workspaces()->updateExistingPivot($workspaceId, ['role' => 'new role value']); 

ve Pivot ilk örnekte görüldüğü attach yöntemleri ikinci parametre olarak niteliklerini geçen doğru şekilde kullanabilirsiniz asla. Bu, daha fazla veritabanı ifadeleri ve kod çürümesi ile sonuçlanacaktır çünkü normal yolu yapmamanızı her zaman hatırlamanız gerekir. Her geliştiriciyi ya da kendinizin bile, amaçlanan ikinci parametreyle attach yöntemini kullanmamayı bildiğinizi düşünüyorsanız, daha sonra ciddi sorunlarla karşılaşabilirsiniz.

Solution

bazı çılgın uzanan yapmalıdır Pivot sütunlarda mutator ile attach arama yapabilmek için (denenmemiş ve kusurlu). Bunu test etmedim ama denemeyi düşünüyorsanız, doğru yolda olmanızı sağlayabilir.

use Illuminate\Database\Eloquent\Relations\BelongsToMany; 

class UserWorkspaceBelongsToMany extends BelongsToMany { 
    public function attach($id, array $attributes = [], $touch = true) 
    { 
     $role = $attributes['role']; 
     unset($attributes['role']); 
     parent::attach($id, $attributes, $touch); 
     $this->updateExistingPivot($id, ['role' => $role], $touch); 
    } 
    // You will need sync here too 
} 

Şimdi her Model::belongsToMany Normal BelongsToMany yerine yeni UserWorkspaceBelongsToMany sınıfını kullanın yapmak zorunda: Biz ilk BelongsToMany uzanır ve özel attach yöntemi uygular kendi ilişki sınıfı oluşturmak gerekir. Bizim Kullanıcı ve Çalışma Alanı sınıfında belongsToMany alay bunu: Gördüğünüz gibi

// put this in the User and Workspace Class 
public function userWorkspaceBelongsToMany($related, $table = null, $foreignKey = null, $otherKey = null, $relation = null) 
{ 
    if (is_null($relation)) { 
     $relation = $this->getBelongsToManyCaller(); 
    } 

    $foreignKey = $foreignKey ?: $this->getForeignKey(); 

    $instance = new $related; 

    $otherKey = $otherKey ?: $instance->getForeignKey(); 

    if (is_null($table)) { 
     $table = $this->joiningTable($related); 
    } 

    $query = $instance->newQuery(); 

    return new UserWorkspaceBelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation); 
} 

, hala veritabanı daha aradığınız ama biz Pivot özellikleri ile attach çağıran birisi hakkında endişelenmenize gerek yoktur ve Mutasyona uğramıyorlar.

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

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

'UserWorkspaceBelongsToMany' sınıfında gerçekten sabit kod yazıyorsunuz. – lcjury

İlgili konular