Frage

Ich habe die folgenden Tabellen:

Benutzer:

userID
...

Lektion:

lessonID
...

Users_Lessons_Status (fungiert als Pivot-Tabelle und enthält andere Informationen):

userID references User.userID
lessonID references Lessons.lessonID
latestSectionID
percentComplete

Was ich tun möchte, ist, dass für jeden Benutzer für jede Lektion eine Zeile in der Pivot-Tabelle vorhanden sein sollte, aus der hervorgeht, wie viel der Benutzer in dieser Lektion abgeschlossen hat und wie seine letzte Abschnitts-ID lautete.Das heißt, es sollte ein eindeutiges Paar mit geben userID und lessonID (primärschlüssel?).

Ich habe meine Modelle so eingerichtet:

<?php

class User extends Eloquent implements UserInterface, RemindableInterface {

...


    public function lessonStatuses() 
    {
        return $this->belongsToMany('Lesson', 'users_lessons_status', 'lessonID', 'userID')->withPivot('latestSectionID', 'percentComplete');
    }

}

<?

class Lesson extends Eloquent {

protected $table = 'lessons';
protected $primaryKey = 'lessonID';

public function userStatuses()
{
    return $this->belongsToMany('User', 'users_lessons_status', 'userID', 'lessonID');
}


}

?>

Meine aktuelle Route sieht so aus:

Route::post('dbm/users/setLatestSectionID', function() {
    if(Auth::check()) {
        $user = User::find(Input::get('userID'));
        $lesson = Lesson::find(Input::get('lessonID'));
        $us = $user->lessonStatuses(); 
        $us->attach($lesson->lessonID, 
            ["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
    }
});

Dies funktioniert, erstellt jedoch jedes Mal eine neue Zeile, wenn ich sie für dasselbe aktualisiere userID und lessonID, also ist das Paar nicht mehr einzigartig.Welche Methoden sollte ich für diesen Zweck verwenden?Ich habe beides ausprobiert save(), attach() und push() in der Dokumentation, aber ich bin mir nicht sicher, welche ich hier verwenden soll.

Bearbeiten:zur Verdeutlichung sollte die resultierende Tabelle ungefähr so aussehen:

id|userID|lessonID|latestSectionID|percentComplete
1    1      1             X             Y
2    1      2        
3    1      3         
4    2      1          
5    3      1
6    3      2
....

Bearbeiten 2:Das Problem wurde behoben User->belongsToMany() methode und fügte die hinzu withPivot nennen.

War es hilfreich?

Lösung

Es scheint ein Fehler zu sein, trotzdem können Sie dies tun:

...->sync([$id], false); // detaching set to false, so it will only insert new rows, skip existing and won't detach anything

bearbeiten:Wie im Kommentar gesagt - es funktioniert bei Ihnen nicht, da Sie Pivot-Daten festlegen möchten.Grundsätzlich gibt es im Moment keine Methode, um dies zu tun, aber so etwas sollte reichen:

// belongsToMany.php
public function attachOrUpdate($id, array $attributes = array(), $touch = true)
{
    if ($id instanceof Model) $id = $id->getKey();

    if ( ! $this->allRelatedIds()->contains($id)) // getRelatedIds() in prior to v5.4
    {
        return $this->attach($id, $attributes, $touch); 
    }
    else if ( ! empty($attributes))
    {
        return $this->updateExistingPivot($id, $attributes, $touch);
    }
}

Ich werde es testen und wenn es besteht, sende eine Pull-Anfrage an 4.1

Andere Tipps

Ich bin dem kürzlich begegnet und habe es auf diese Weise behoben:

Verwenden updateExistingPivot zuerst und überprüfen Sie das Ergebnis, wenn das Ergebnis ist 1 es bedeutet, dass es Reihen mit dem gleichen gab userID und lessonID und es wurde erfolgreich aktualisiert, andernfalls, wenn das Ergebnis ist 0 es bedeutet, dass es keine Zeilen damit gab userID und lessonID, damit Sie es anhängen können, um eine neue Zeile zu erstellen

    $update_result = $us->updateExistingPivot($lesson->lessonID, 
            ["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
    if($update_result == 0) {
        $us->attach($lesson->lessonID, 
            ["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')] );
    }

Sie sollten verwenden updateExistingPivot().

Aktualisieren Sie Ihren zu verwendenden Code

    $us->updateExistingPivot($lesson->lessonID, 
        ["latestSectionID" => Input::get('latestSectionID'), "percentComplete" => Input::get('percentComplete')], true );

Der letzte Parameter aktualisiert die Zeitstempel für alle zugehörigen Modelle.Wenn nicht, können Sie entfernen oder auf false setzen.

Wenn Sie nur anhängen möchten, wenn kein Datensatz vorhanden ist, können Sie so etwas tun...

Route::post('dbm/users/setLatestSectionID', function() {
    if(Auth::check()) {
        $user = User::find(Input::get('userID'));

        $lesson = [
            "latestSectionID" => Input::get('latestSectionID'), 
            "percentComplete" => Input::get('percentComplete')
        ];

        $num_lessons = $user->lessonStatuses()->where('id', Input::get('lessonID'))->count();

        if($num_lessons == 0) {
            $user->attach($lesson->lessonID, $lesson);
        } else {
            $user->updateExistingPivot($lesson->lessonID, $lesson);

        }
    }
});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top