Dies ist eine schwierige Frage. Die Lösungen, die ich mir vorstellen kann, sind stinkend und können später zu Problemen führen.
Ich werde die Antwort von Patricus erweitern, damit es funktioniert.
Ich wollte Patricus 'Antwort kommentieren, aber es gibt einfach zu viel zu erklären. Um seine Lösung mit attach
und sync
arbeiten zu lassen, müssen wir einige hässliche Dinge tun.
Das Problem
Lassen Sie uns zunächst das Problem mit seiner Lösung identifizieren. Seine Getter und Setter funktionieren, aber die anglo-to-Many-Beziehung verwendet das Pivot-Modell nicht, wenn sync
, attach
oder detach
ausgeführt wird. Dies bedeutet, dass jedes Mal, wenn wir einen dieser Parameter mit dem Parameter $attributes
aufrufen, die nicht mutierten Daten in die Datenbankspalte übernommen werden.
// This will skip the mutator on our extended Pivot class
$user->workspaces()->attach($workspace, ['role' => 'new role value']);
Wir konnte nur versuchen, sich daran zu erinnern, dass jedes Mal, wenn wir eine von diesen nennen wir nicht den zweiten Parameter verwenden können, die die mutierten Daten zu befestigen und rufen Sie einfach updateExistingPivot
mit den Daten, die mutiert werden müssen.So wäre ein attach
sein, was Patricus erklärte:
$user->workspaces()->attach($workspace);
$user->workspaces()->updateExistingPivot($workspaceId, ['role' => 'new role value']);
und wir konnten nie die richtige Art und Weise der Weitergabe der Dreh als attach
zweiten Parameter im ersten Beispiel gezeigt Methoden-Attribute verwenden. Dies führt zu mehr Datenbank-Anweisungen und Code-Fäulnis, weil Sie immer daran denken müssen, nicht den normalen Weg zu gehen. Sie könnten später zu ernsthaften Problemen kommen, wenn Sie annehmen, dass jeder Entwickler oder selbst Sie nur wissen, die Methode attach
nicht mit dem zweiten Parameter zu verwenden, wie es beabsichtigt war.
Die Lösung (ungetestet und unvollkommen)
Zur Anzeige attach
an den Schwenksäulen mit dem Mutator rufen Sie etwas verrückt erstreckt tun müssen. Ich habe das nicht getestet, aber es kann Sie auf den richtigen Weg bringen, wenn Sie Lust haben, es zu versuchen. Wir müssen zuerst unsere eigenen Beziehungsklasse erstellen, die BelongsToMany
und implementiert unsere eigene attach
Methode erweitert:
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
}
Jetzt müssen wir jedes Model::belongsToMany
unsere neue UserWorkspaceBelongsToMany
Klasse anstelle des normalen BelongsToMany
nutzen machen. Wir tun dies, indem Sie die belongsToMany
in unserem User und Workspace-Klasse spöttisch:
// 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);
}
Wie Sie sehen können, rufen wir noch die Datenbank mehr, aber wir müssen über jemanden keine Sorge attach
mit den Dreh Attribute aufrufen und Sie werden nicht mutiert.
Jetzt verwenden, die in Ihrem Modell anstelle des normalen belongsToMany:
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');
}
}
Ich versuche, es manuell zu tun. Hier ist, was ich habe: http://laravel.io/bin/RE2ze – ATLChris