2009-09-26 16 views
9

Ich bin ein wenig verwirrt darüber, wie das funktioniert, auch wenn es richtig funktioniert. Ich habe ein Modell, das zwei Assoziationen zu demselben anderen Modell hat.has_one und has_many im selben Modell. Wie verfolgen Schienen sie?

Unternehmen hat einen Besitzer und Unternehmen hat viele Mitarbeiter der Klasse Benutzer.

hier ist mein Unternehmen Modell:

class Company < ActiveRecord::Base 
    validates_presence_of :name 

    has_many :employee, :class_name => 'User' 
    has_one :owner, :class_name => 'User' 
    accepts_nested_attributes_for :owner, :allow_destroy => true 
end 

hier ist mein Benutzermodell:

class User < ActiveRecord::Base 
    include Clearance::User 
    attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem 
    validates_presence_of :lastname, :firstname 
    belongs_to :company 
end 

Jetzt vorausgesetzt, ich habe 3 Mitarbeiter des Unternehmens, einschließlich der Eigentümer. Wenn ich das Unternehmen zum ersten Mal erstelle, setze ich den Eigentümer auf den Mitarbeiter mit der ID 1 und die beiden anderen (2,3) werden auf die Mitarbeiterliste gesetzt, indem man ihre Firmen-ID (user.company = Firma) setzt. Alle drei haben ihre Firmen-ID auf die Firmen-ID, die wir annehmen können, ist 1

wenn ich für company.owner frage, bekomme ich den richtigen Benutzer und wenn ich company.employee mache, bekomme ich alle drei.

Wenn ich den Besitzer zu Benutzer 2 ändere, wird Benutzer 1 automatisch von den Mitarbeitern entfernt, indem seine Firmen-ID auf Null gesetzt wird. Das ist in Ordnung, und wenn ich ihn als einfacher Angestellter hinzufüge, ist alles noch gut.

Wie zum Teufel Schienen wissen, was ist das? Was ich meine ist, wie weiß es, dass ein Angestellter Eigentümer und nicht nur ein Angestellter ist? Nichts im Schema definiert dies.

Ich habe das Gefühl, ich sollte die Eigentümervereinigung rückgängig machen und Firma gehörigen zu einem Benutzer machen.

Antwort

12

Wie Sie es jetzt haben, gibt es nichts, um Besitzer von Mitarbeitern zu unterscheiden. Das bedeutet, dass Sie Probleme bekommen werden, sobald Sie anfangen, Leute zu entfernen oder zu versuchen, den Besitz zu wechseln.

Wie François hervorhebt, ist es ein Glück, dass der Besitzer der Benutzer ist, der zur Firma mit der niedrigsten ID gehört.

Um das Problem zu beheben, hätte ich meine Modelle in der folgenden Manier beziehen.

Sie müssen eine weitere Spalte namens owner_id zur Companies-Tabelle hinzufügen, aber dies definiert Ihre Beziehungen klarer. Und vermeidet jegliche Probleme, die mit dem Besitzerwechsel verbunden sind. Beachten Sie, dass es möglicherweise eine zyklische Abhängigkeit gibt, wenn Sie diese Route gehen und Ihre Datenbank so eingestellt haben, dass beide Benutzer gleichzeitig arbeiten.company_id und companies.owner_id dürfen nicht null sein.

Ich bin mir nicht ganz sicher, wie gut access_nested_attributes_for mit einer belongs_to-Beziehung spielen wird.

+0

Beendet auf diese und auf der Benutzerseite, habe ich Associated_to: Arbeitgeber,: Class_name => "Firma", die ich tun musste, um einen Konflikt mit user.company zu verhindern, jetzt user.company ist das Unternehmen und die Firma .employer ist ... Sie bekommen den Punkt: P – nkassis

0

Sie könnten ein Modell namens Besitz haben -

ownership belongs_to company 
ownership belongs_to user 

user has_many ownerships 
company has_one ownership 
5

has_one ist syntaktischer Zucker für:

has_many :whatevers, :limit => 1 

hat man das :limit => 1 Bit addiert, wodurch nur 1 Datensatz zu gewährleisten jemals zurückgeführt wird. Stellen Sie sicher, dass Sie in Ihrer Deklaration eine :order-Klausel haben, um unter allen Umständen den richtigen Datensatz zurückzugeben. In diesem Fall würde ich dem Mitarbeiter eine Markierung zuweisen, um anzuzeigen, wer der Eigentümer ist, und nach dieser Spalte sortieren, um den richtigen Datensatz zu erhalten.

Ihre Frage darüber, woher Rails das weiß, ist, weil die meisten Datenbanken Datensätze in ihrer primären Schlüsselreihenfolge zurückgeben werden. Der 1. hinzugefügte Mitarbeiter hat die ID 1 und wird somit als 1. zurückgegeben.

Verwandte Themen