2009-07-10 12 views
2

Unter Berücksichtigung der folgenden Ressourcen mit den entsprechenden Beziehungen:Schienen: Polymorph oder nicht?

Site 
has_many :page 
has_many :groups 
has_many :projects 

Group 
belongs_to :site 
has_many :pages 

Project 
belongs_to :site 
has_many :pages 

Ist es gut, Seite Modell polymorpher oder lassen einzelne Fremdschlüssel zu machen?

**Scenario 1 (Polymorphic)** 
Page 
pageable_id 
pageable_type 
title 
body 
.... 
.... 

**Scenario 2 (Non Polymorphic)** 
Page 
site_id (always filled) 
group_id (may be empty) 
project_id (may be empty) 
title 
body 
.... 
.... 

**Scenario 3 (Combination)** 
Page 
site_id 
pageable_id (may be empty, if page belongs only to site) 
pageable_type (may be empty, if page belongs only to site) 
title 
body 
..... 
..... 

Welche der oben genannten drei Szenarien würden Sie bevorzugen? Und warum (in Bezug auf Effizienz, etc ..)

Hinweis: In meinen Ansichten, werde ich alle durch die möglichen Beziehungen der Seite werden durchquere die entsprechenden Links zu zeigen (zum Beispiel: wenn die Seite gehört zu gruppieren, zeige ich den zurück zu Gruppenlink, ...)

Antwort

0

Ich denke, die site_id im Modell ist nicht so eine gute Idee, denn es könnte brechen, wenn die site_id einer Seite gehört zu einer Gruppe doesn ' t stimmen mit der site_id dieser Gruppe überein.

Das lassen würde nur Szenario 1 ...

Wenn Sie die Möglichkeit haben wollen, ein site.pages zu tun und alle Seiten zu dieser Website erhält so (auch zu einer Gruppe zu dieser Website gehören, gehören, Seiten) Sie können Ihre eigene Funktion natürlich schreiben.

class Site 
    def all_pages 
    Page.find_by_sql(["SELECT p.* FROM pages p, sites s, groups g, projects j WHERE (p.pageable_type='Site' AND p.pageable_id=?) OR (p.pageable_type='Group' AND p.pageable_id=g.id AND g.site_id=?) OR (p.pageable_type='Project' AND p.pageable_id=j.id AND j.site_id=?, self.id, self.id, self.id]) 
    end 
end 

(auch würde ich die pageable_id Spalte ‚parent_id‘ und pageable_type ‚PARENT_TYPE‘ in diesem Fall Name, der mir mehr logisch erscheint ...)

+0

Ich mag Ihre Herangehensweise an die Auswahl aller Seiten, aber wie geht es? o break - "Ich denke, das Einbinden der site_id in das Modell ist nicht so eine gute Idee, da es brechen könnte, wenn die site_id einer Seite, die zu einer Gruppe gehört, nicht mit der site_id dieser Gruppe übereinstimmt." Eine Gruppe muss sich auf einer Site befinden und darf sich nicht von Site zu Site ändern. – Dharam

+0

Angenommen, Sie haben eine Seite und möchten die dazugehörige Seite finden. Wenn Sie die Site-ID in das Seitenmodell einschließen, gibt es zwei Möglichkeiten (Seite gehört zu einer Gruppe): page.site & page.group.site. In den meisten Fällen führen diese zum selben Site-Objekt, jedoch muss es * nicht sein (da 2 site_ids involviert sind). Obwohl es eine kleine bis keine Chance gibt, dass das passieren wird, würde ich versuchen, solche Konstruktionen um jeden Preis zu verhindern. –

+0

@Jongsma - danke für die schnelle Rückmeldung. – Dharam