Frage

Ich frage mich, was der beste Weg, um eine Beziehung zu modellieren, wo ein Objekt mit genau n Objekten einer anderen Klasse zugeordnet ist. Ich mag die has_one Beziehung auf einen bestimmten Wert von n erweitern.

Zum Beispiel würde ein TopFiveMoviesList zu Benutzern gehört und hat genau fünf Filme. Ich könnte mir vorstellen, dass die zugrunde liegenden SQL-Tabellenfelder haben würden wie movie_id_1, movie_id_2, ... movie_id_5.

Ich weiß, ich könnte eine has_many Beziehung tun und die Zahl der Kinder auf Modellebene begrenzen, aber ich möchte lieber nicht einen Vermittler Tisch.

War es hilfreich?

Lösung

Mein erster Instinkt wäre, einen Tisch kommen, aber wenn das nicht wünschenswert User.movie[1-5]_id Spalten die Rechnung passen würden. (Ich denke, movie1_id paßt besser mit Rails-Konvention als movie_id_1.)

Da Sie diese Rails und Active markiert, werde ich etwas völlig ungetestet und wahrscheinlich etwas falsch Modell-Code auf meine Antwort hinzuzufügen. :)

class User < ActiveRecord::Base
  TOP_N_MOVIES = 5
  (1..TOP_N_MOVIES).each { |n|  belongs_to "movie#{n}".to_sym, :class_name => Movie }
end

Sie können diese Zeile in einer Makro-Stil Methode wickeln, aber es sei denn, wenn es das ist ein gemeinsames Muster für Ihre Anwendung, das zu tun wird wahrscheinlich nur den Code, dass härter mit wenig DRY Nutzen zu lesen.

Sie möchten vielleicht auch Validierungen hinzufügen, um sicherzustellen, dass es keine doppelten Filme auf einem Benutzerliste enthalten sind.

Verknüpfen Sie Ihre Film-Klasse an den Benutzer zurück ist ähnlich.

class Movie < ActiveRecord::Base

  (1..User::TOP_N_MOVIES).each do |n| 
    has_many "users_list_as_top_#{n}".to_sym, :class_name => User, :foreign_key => "movie#{n}_id"
  end

  def users_list_as_top_anything
    ary = []
    (1..User::TOP_N_MOVIES).each {|n| ary += self.send("users_list_as_top_#{n}") }
    return ary
  end

end

(Natürlich, die users_list_as_top_anything wahrscheinlich besser als expliziten SQL geschrieben werden würden. Ich bin faul heute.)

Andere Tipps

Ich denke, die Umsetzung dieses Modells durch ein Join-Modell Sie sind beste Wette hier sein wird. Es ermöglicht das List Modell über Listenlogik und Movie Modell zu befürchten Film Logik zu kümmern. Sie können einen Nomination erstellen (Name nicht der größte, aber Sie wissen, was ich meine) Modell, das die Beziehung zwischen Film und Listen zu handhaben, und wenn eine Grenze von 5 da ist, könnten Sie einfach die Anzahl der Nominierungen begrenzen Sie zurück ziehen.

Es gibt ein paar Gründe, warum ich denke, dieser Ansatz besser ist.

Als erstes vorausgesetzt, Sie wollen die Beziehungen zu durchqueren können, in beiden Richtungen (movie.lists und list.movies), der 5-Säule Ansatz wird viel chaotischer sein.

Während es so wäre viel besser für Active has n Beziehungen zu unterstützen, tut es nicht, und so werden Sie auf, dass man den Rahmen kämpfen. Auch scheint die has n Beziehung ein bisschen spröde ich in dieser Situation. Ich habe nicht diese Art der Umsetzung gesehen in Active abziehbar, obwohl ich es geschehen zu sehen, wirklich interessiert sein würde. :)

Ich nehme an, Sie „implementieren“ und nicht als „Modell“ verstehen? Die Modellierung ist ziemlich einfach, in UML, sagen, wo Sie eine Person Unternehmen haben, die aus 5 Filmeinheiten hergestellt wird.

Aber die Schwierigkeit kommt, wenn man has_one sagen, has_5 gehen. Wenn es ein einfacher skalar Wert ist, has_one ist vielleicht eine Eigenschaft auf der übergeordneten Einheit. Has_5 ist wahrscheinlich 2 miteinander durch eine kontrollierte Unternehmen Beziehung in UML „setzt sich zusammen aus“.

Die wichtigste Frage zu beantworten, ist wahrscheinlich: „Können Sie garantieren, dass es immer‚Top 5‘sein?“ Wenn ja, Modell mit Spalten, wie Sie bereits erwähnt. Wenn nein, Modell es mit einem anderen Unternehmen.

Eine andere Frage ist vielleicht: „Wie leicht wird es Refactoring sein?“ Wenn es einfach ist, Heck, mit 5 Spalten beginnen und Refactoring Einheiten zu trennen, wenn es jemals ändert.

Wie üblich „beste“ ist abhängig von dem geschäftlichen und technischen Umfeld.

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