Abrufen des Werts einer zusätzlichen Pivot-Tabellenspalten-Laravel


71

Ich habe eine Pivot-Tabelle für phone_models, phone_problems und phone_model_phone_problem. Die Pivot-Tabelle hat eine zusätzliche Spalte 'Preis'.

Handy-Modell:

class PhoneModel extends \Eloquent
{
    public function problems()
    {
        return $this->belongsToMany('RL\Phones\Entities\PhoneProblem')->withPivot('price');
    }
}

Telefonproblem:

class PhoneProblem extends \Eloquent
{
    public function models()
    {
        return $this->belongsToMany('PhoneModel')->withPivot('price');
    }
}

Ich versuche, den Preis eines bestimmten Telefons mit einem bestimmten Problem zu ermitteln.

So habe ich es jetzt, aber ich habe das Gefühl, dass Laravel eine eingebaute Eloquent-Funktion hat, die ich nicht viel einfacher finden kann:

$model = $this->phoneService->getModelFromSlug($model_slug);
$problem = $this->phoneService->getProblemFromSlug($problem_slug);

Alles, was dies tut, ist die Auswahl des spezifischen Modells und Problems aus ihrer Schnecke.

dann mache ich mit diesen Anmeldeinformationen den Preis wie folgt:

$row = DB::table('phone_model_phone_problem')
->where('phone_model_id', '=', $model->id)
->where('phone_problem', '=', $problem->id)
->first();

Jetzt kann ich den Preis so bekommen, $row->priceaber ich denke, es muss einen viel einfacheren und "Laravel" Weg geben, dies zu tun.

Antworten:


141

Wenn Sie viele zu viele Beziehungen mit Eloquent verwenden, wird dem resultierenden Modell automatisch ein pivotAttribut zugewiesen. Über dieses Attribut können Sie auf Pivot-Tabellenspalten zugreifen. Obwohl standardmäßig nur die Schlüssel im Pivot-Objekt vorhanden sind. Um Ihre Spalten auch dort zu platzieren, müssen Sie sie beim Definieren der Beziehung angeben:

return $this->belongsToMany('Role')->withPivot('foo', 'bar');

Offizielle Dokumente

Wenn Sie weitere Hilfe bei der Konfiguration der Beziehungen zu Eloquent benötigen, lassen Sie es mich wissen.

Bearbeiten

Um den Preis abzufragen, tun Sie dies

$model->problems()->where('phone_problem', $problem->id)->first()->pivot->price

Ich habe meine Frage aktualisiert, damit Sie meine Beziehungen sehen können
— Rodrigo

Könnte jemand zeigen, wie eine Pivot-Tabelle basierend auf einer zusätzlichen Spalte abgefragt wird, wie pricein diesem Beispiel von oben$model->problems()->where('phone_problem', $problem->id)->first()->pivot->price
— Brent Connor

Wie wäre es, wenn Sie den Wert dieses Pivot-Eintrags nicht erhalten, sondern wie den Preis festlegen?
— Bartu

@ Bartu das sollte funktionieren : $model->problems()->updateExistingPivot($problemId, ['price' => $newPrice]). Wenn nicht, stellen Sie bitte eine neue Frage, da die Kommentare nicht wirklich der richtige Ort dafür sind.
— lukasgeiter

es funktioniert, vielleicht können Sie es als weitere Referenz für andere Leute hinzufügen.
— Bartu

18

So rufen Sie Daten aus der Pivot-Tabelle ab:

$price = $model->problems()->findOrFail($problem->id, ['phone_problem'])->pivot->price;

Oder wenn Sie viele Platten mit unterschiedlichem Preis haben:

$price = $model->problems()->where('phone_problem', $problem->id)->firstOrFail()->pivot->price;

Und dazu.

Um die Daten im Pivot zu aktualisieren, gehen Sie auf NEUEN WEG :

$model->problems()->sync([$problemId => [ 'price' => $newPrice] ], false); 

Wenn der 2. Parameter auf false gesetzt ist, bedeutet dies, dass Sie nicht alle anderen verwandten Modelle trennen.

Oder gehen Sie alten Weg

$model->problems()->updateExistingPivot($problemId, ['price' => $newPrice]);

Und erinnere dich:

So löschen Sie :

$model->problems()->detach($problemId);

So erstellen Sie neue:

$model->problems()->attach($problemId, ['price' => 22]);

Es wurde getestet und hat bewiesen, dass es in Laravel 5.1 funktioniert. Lesen Sie mehr.


2
Idealerweise ist es noch besser zu aktualisieren updateExistingPivot(). In Laravel 5.6 ist es auch möglich, die Funktion zu verwenden, anstatt sie falseals zweiten Parameter zu übergeben . sync()syncWithoutDetaching()
— Dim13i

3

Laravel 5.8 ~

Wenn Sie ein benutzerdefiniertes Pivot-Modell erstellen möchten, können Sie dies tun:

Account.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Account extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class)
            ->using(AccountUserPivot::class)
            ->withPivot(
                'status',
                'status_updated_at',
                'status_updated_by',
                'role'
            );
    }
}

AccountUserPivot.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class AccountUserPivot extends Pivot
{
    protected $appends = [
        'status_updated_by_nice',
    ];

    public function getStatusUpdatedByNiceAttribute()
    {
        $user = User::find($this->status_updated_by);

        if (!$user) return 'n/a';

        return $user->name;
    }
}

Im obigen Beispiel Accounthandelt es sich um Ihr normales Modell, und Sie haben $account->usersdie account_userJoin-Tabelle mit Standardspalten account_idund user_id.

Wenn Sie ein benutzerdefiniertes Pivot-Modell erstellen, können Sie den Spalten der Beziehung Attribute und Mutatoren hinzufügen. Wenn Sie im obigen Beispiel das AccountUserPivot-Modell erstellt haben, weisen Sie Ihr Account-Modell an, es über zu verwenden ->using(AccountUserPivot::class).

Dann können Sie auf alles zugreifen, was in den anderen Antworten hier gezeigt wird, aber Sie können auch auf das Beispielattribut über zugreifen $account->user[0]->pivot->status_updated_by_nice(vorausgesetzt, dies status_updated_byist ein Fremdschlüssel für eine ID in der Benutzertabelle).

Weitere Dokumente finden Sie unter https://laravel.com/docs/5.8/eloquent-relationships (und ich empfehle, STRG + F zu drücken und nach "Pivot" zu suchen).


Vielen Dank mein Freund
— Ali Sharifineyestani
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.