2009-06-01 11 views
3

In einem ActiveRecord (CakePHP aromatisiert) Setup habe ich eine HasAndBelongsToMany Zuordnung auf Videos und Bins: Ein Bin kann n Referenzen auf Videos speichern, und Videos können dazu gehören n Behälter.Sortierreihenfolge für Artikel in einer HABTM-Zuordnung speichern - CakePHP

Ich muss in der Lage sein, die Anzeigereihenfolge der Videos in einem bestimmten Bin manuell einzustellen und zu speichern (so kann der Kunde seine Videos in einer bestimmten Reihenfolge innerhalb des Bin haben.) Mein erster Gedanke ist, ein Feld zu erstellen Bin, der ein Array von Video-IDs in der Reihenfolge speichert, in der sie angezeigt werden sollen. Ist das der effizienteste Weg, damit umzugehen?

Wenn ja, wenn ich dann das HABTM-Abfrageergebnis erhalte, was ist der sauberste/effizienteste Weg, die zurückgegebene Abfrage neu zu ordnen, damit sie dem sortierten Array von IDs entspricht?

Die Videos mit einem Bin zugeordnet sind, als Array zurückgegeben:

[Video] => Array 
      (
       [0] => Array 
        (
         [id] => 49b2de95-0338-48b9-bc88-01ba35664358 
         ... 

        ) 

       [1] => Array 
        (
         [id] => 49b1ccad-b770-410e-be46-03a035664358 
         ... 
      ) 

Oder gibt es einen besseren Weg, um zu erreichen, was ich versuche, ohne HABTM Assoziationen zu tun?

Vielen Dank im Voraus -

Antwort

6

Was, wenn zu tun HABTM kompliziert wird?

Standardmäßig speichert Cake beim Speichern einer HasAndBelongsToMany-Beziehung alle Zeilen in der Join-Tabelle, bevor neue gespeichert werden. Zum Beispiel, wenn Sie einen Club haben, dem 10 Kinder zugeordnet sind. Sie aktualisieren dann den Club mit 2 Kindern. Der Club wird nur 2 Kinder haben, nicht 12.

Beachten Sie auch, dass wenn Sie weitere Felder zum Join hinzufügen möchten (wenn es erstellt wurde oder Meta-Informationen) dies mit HABTM Join-Tabellen möglich ist, aber es wichtig ist verstehe, dass du eine einfache Option hast.

HasAndBelongsToMany zwischen zwei Modellen ist in Wirklichkeit eine Abkürzung für drei Modelle, die sowohl durch eine hasMany-Verknüpfung als auch eine assignesTo-Verknüpfung verknüpft sind.

Betrachten Sie dieses Beispiel:

Child hasAndBelongsToMany Club 

Ein anderer Weg, zu betrachten dies eine Mitgliedschaft Modell ist das Hinzufügen

Child hasMany Membership 
Membership belongsTo Child, 
ClubClub hasMany Membership. 

Diese beiden Beispiele derselben fast genau sind. Sie verwenden die gleiche Menge und benannte Felder in der Datenbank und die gleiche Anzahl von Modellen. Die wichtigen Unterschiede sind, dass das "Join" -Modell anders benannt wird und sein Verhalten vorhersehbarer ist.

In Ihrem Beispiel benötigen Sie eine Möglichkeit zum Hinzufügen und Entfernen ohne Bearbeitung anderer Benutzer Video-Links, daher Standard-Gewohnheit wird Ihnen nicht sehr gut. Erstellen Sie ein Modell für diesen "Join", ähnlich dem oben beschriebenen Mitgliedschaftsmodell. Wenn Sie ein Gewichtungsfeld hinzufügen, können Sie außerdem die ordered behavior (die ich geschrieben habe) verwenden, um jeden Satz Videos pro Bin zu bestellen. Dann würden Sie die folgenden Felder

id, bin_id, video_id, weight 

verwenden Und bin_id als ‚foreign_key‘ im Verhalten Configuartion einrichten. Viel Glück

+0

Richtig. Anstatt die integrierten HABTM-Zuordnungen zu verwenden, erstellt Ihre Methode eine Join-Tabelle, um jedem Video einen Datensatz mit Metadaten (Gewichtung usw.) zuzuordnen, der eine feinkörnige Kontrolle über die Abfrage bietet. So konnte ich die "Mitgliedschaft" -Rekorde nach "Gewicht" bestellen, um meine korrekte Bestellung zu erhalten. –

+0

gut ich bin nicht sicher, ob Sie es richtig sehen. Was ich vorschlage, ist, wegd von Habtm, und damit HABTM, und nur ein drittes Modell, das zu Video und Bin gehört, und ist bestellt. –

+0

Nein, ich denke, wir sagen das Gleiche. Das neue dritte Modell speichert alle Metadaten, die das Bin für das Video benötigt, und ich kann es nach jedem Feld sortieren. Aber zu einem früheren Punkt von Ihnen: Konnte ich nicht fügen Sie ein Feld 'Reihenfolge' der Join-Tabelle VideosBins HABTM und dann sortieren die abgerufenen Daten durch dieses zusätzliche Feld mit Set :: sort (von Herrn Lecter unten)? –

0

Ich weiß nicht über "effizienteste" Art zu implementieren, was Sie wollen, das hängt von Ihrer gesamten Anwendung und was Sie erreichen möchten.Ich denke nur daran, dass die einfachste Lösung oft die beste ist.

Allerdings kann ich Ihnen einen Tipp für die Sortierung Ihrer Video-Array geben! Es ist ziemlich einfach:

am Set class für mehr Süßigkeiten Werfen Sie einen Blick. :)

+0

Das löst das Problem nicht wirklich, aber danke für den Kopf. Ich habe Set für andere Dinge verwendet, habe aber nicht zu viel damit getan (meistens Set :: extract). Ich denke, ich könnte Set :: sort verwenden, um das Problem teilweise zu lösen (siehe Kommentar zu A. Morland oben) –

2

Nun, ich habe gerade versucht, dieses Problem zu lösen und ich denke, die einfachste Lösung möglich gefunden:

Wenn eine neue Ordnung der zugehörigen Modelle Speichern Sie die bestehenden Beziehungen löschen und die neuen in der gewünschten Reihenfolge hinzufügen . Dies bedeutet, dass die erstellten IDs in Ihrer Sortierreihenfolge ausgeführt werden und Sie einfach nach ID sortieren können, um die Bestellung anzuzeigen.

public $hasAndBelongsToMany = array(
    'Item' => array(
     'order' => 'ItemFoldersItem.id ASC, Item.name DESC', 
    ) 
); 

Ziemlich einfach, nicht wahr?

+1

Nun, das einzige Problem ist, dass die zweite Sortierung immer ignoriert wird, da ids natürlich einzigartig sind. Sie müssen also immer noch auf eine Standardsortierreihenfolge achten, die nicht von den IDs sein sollte. – Uli

Verwandte Themen