2009-06-02 12 views
1

Es ist mir aufgefallen, dass, wenn ich einen has_many Join habe, wo das fremde Modell kein so genanntes_to hat, und der Join also ein Weg ist, dann brauche ich eigentlich keinen Fremdschlüssel.Muster für unidirektionale has_many beitreten?

Wir könnten eine Spalte haben, category_ids, die ein gemarsared Array von IDs speichert, die wir an find übergeben können.

Hier ist also ein nicht getestet Beispiel:

class page < AR 

    def categories 
    Category.find(self.category_ids) 
    end 

    def categories<<(category) 
    # get id and append to category_ids 
    save! 
    end 

    def category_ids 
    @cat_ids ||= Marshal.load(read_attribute(:category_ids)) rescue [] 
    end 

    def category_ids=(ids) 
    @cat_ids = ids 
    write_attribute(:category_ids, ids) 
    end 

end 

page.category_ids => [1,4,12,3] page.categories => Array der Kategorie

Gibt es akzeptiert Muster für das schon? Ist es üblich oder einfach nicht die Mühe wert?

+0

Was ist die Motivation dafür? Welches Problem löst es? – tomafro

Antwort

1

Würde die Leistung nicht darunter leiden, wenn Sie ein Marshalling/Unmarshalling durchführen?

Ich persönlich denke nicht, dass dies die Mühe wert ist und was Sie versuchen, scheint nicht klar zu sein.

Eigentlich sieht es wie ein many-to-many-Mapping anstatt ein many-to-one, da es keinen Code, der von der Zugehörigkeit zu mehr als einer Seite eine Kategorie verhindert, sicher wollen Sie so etwas wie:

create table categories_pages (
    category_id integer not null references categories(id), 
    page_id integer not null references pages(id), 
    primary_key(category_id, page_id) 
); 

mit entweder hat und gehört zu vielen auf beiden Seiten oder has_many: auf beiden Seiten (je nachdem, ob Sie mehr Zeug speichern möchten).

+0

Ich denke, es wäre gleichbedeutend mit: Seite has_many Kategorien. Da es keine Möglichkeit gibt, category.pages mit diesem Code zu erstellen. Wie auch immer eine Kategorie zu mehr als einer Seite gehören könnte, würde das Kategoriemodell einfach nie wissen. Ich schätze das nicht wirklich als eine Alternative zu has_many oder HABTM, da es viel begrenzter ist. Es wäre sicherlich ein Overhead zum Marshalling, ich denke, ohne Tests würden wir nicht wissen, ob es größer war als die Magie von Rails, eine has_many-Beziehung hinzuzufügen. – Kris

1

Ich stimme Omar zu, dass dies nicht die Mühe wert ist.

Ihre Datenbank spiegelt nicht mehr Ihr Datenmodell wider und bietet keine Hilfe bei der Durchsetzung dieser Beziehung. Außerdem müssen Sie das Array für die Marshalling-ID nun mit der Tabelle "Category" synchronisieren und die Eindeutigkeit für Pages erzwingen, wenn Sie die Beziehung auf has_many beschränken möchten.

Aber ich denke am wichtigsten, was ist der Vorteil dieses Ansatzes? Es wird die Komplexität erhöhen und die Menge an Code erhöhen, die Sie schreiben müssen.