2009-05-27 7 views
2

J'ai ces tables:Comment modéliser un site multi-blog?

**Sites** 
:has_many :blogs 
:has_many :pages 

**Blogs** 
:belongs_to :site 

**Pages** 
:belongs_to :site 
:belongs_to :blog 

Fondamentalement, je veux être en mesure de créer des pages qui sont soit liés à un site ou lié à un blog avec des itinéraires comme ceci:

/blogs/1/pages/1 
/sites/1/pages/2 

avec ma configuration actuelle, ma table Pages a une foreign_key pour blog_id eT site_id - et je pensais juste de le faire:

  • si une page est créée fo ra site (ce qui signifie qu'il n'appartient pas à un blog) puis définissez blog_id = à NULL, mais définissez site_id en conséquence

  • mais, si une page est créée pour un blog (qui appartient déjà à un site), définissez la site_id connexe eT blog_id

Alors si je veux une liste des pages du site: je peux interroger la table Pages pour tous blog_ids NULL, et si je veux blog pages, je vais les passer à travers la relation avec Blog déjà. MISE À JOUR: J'ai accepté la réponse ci-dessous qui suggérait d'utiliser des «associations polymorphes», mais cela pourrait-il être fait aussi en utilisant Single Table Inheritance? Si oui, quelle est la meilleure méthode?

Merci.

Répondre

5

Vous pouvez utiliser des associations polymorphes.

Ajoutez une clé étrangère et une colonne de type à votre table pages. Trouvez un adjectif qui décrit la propriété commune des classes auxquelles vos pages peuvent appartenir. Je suis venu avec pageable (qui me donne une colonne pageable_id et pageable_type). Si vous utilisez les migrations, ajoutez ce qui suit votre Page migration:

# Adds "pageable_id" integer column and "pageable_type" string column. 
t.references(:pageable, :polymorphic => true) 

Dans vos modèles, spécifiez la relation polymorphes lors de l'utilisation has_many/belongs_to:

class Site < ActiveRecord::Base 
    has_many :pages, :as => :pageable 
end 

class Blog < ActiveRecord::Base 
    has_many :pages, :as => :pageable 
end 

class Page < ActiveRecord::Base 
    belongs_to :pageable, :polymorphic => true 
end 

Et voici:

# Return all pages belonging to Site with ID 12, that is, return all pages 
# with pageable_id 12 and pageable_type "site". 
Site.find(12).pages 

# Return all pages belonging to Blog with ID 3, that is, return all pages 
# with pageable_id 3 and pageable_type "blog". 
Blog.find(3).pages 

# Returns the owner (Blog or Site) of Page with ID 27. 
Page.find(27).pageable 

J'espère que ça aide.

Questions connexes