2010-02-14 15 views
2

J'essaie ma première application avec mongodb sur Rails en utilisant mongo_mapper et je pèse mes options sur un modèle STI comme ci-dessous.mongodb data design question

Cela fonctionne bien, et je vais bien sûr ajouter à cela de plusieurs façons que je peux actuellement compter, je me demandais juste si je ne serais pas mieux avec des documents incorporés ou quelque chose comme ça. Je souhaite que mes modèles partagent le plus possible, IE car ils héritent tous de certains attributs, un formulaire partiel partagé sur la propriété/_form.html.erb ... en plus de leurs propres éléments de formulaire, etc. Je sais que les vues diffèrent mais je ne suis pas encore sûr sur les contrôleurs, car je pourrais utiliser le contrôleur de propriété que je suppose pour la plupart des choses? Et je suis sûr que ça va devenir plus complexe au fur et à mesure.

Toutes les ressources pointeurs et/ou la sagesse (conseils pour économiser de la douleur) serait grandement appréciée

property.rb

class Property 
     include MongoMapper::Document 

     key :name, String, :required => true 
     key :_type, String, :required => true 
     key :location_id, Integer, :required => true 
     key :description, String 
     key :phone, String 
     key :address, String 
     key :url, String 
     key :lat, Numeric 
     key :lng, Numeric 
     key :user_id, Integer, :required => true 
     timestamps! 

    end 

Restaurant

class Restaurant < Property 
    key :cuisine_types, Array, :required => true 

end 

bar

class Bar < Property 
    key :beers_on_tap, Array 

end 
+0

je vais aussi besoin de toutes sortes de liste des choses ... sans modèles spécifiques, à savoir cuisine_types, beers_on_taps ... similaire à l'étiquetage je suppose, mais sans avoir un million de modèles en cours d'exécution autour, collection polymorphes? – holden

+0

Cela a également été utile: http://code.alexreisner.com/articles/single-table-inheritance-in-rails.html – holden

Répondre

3

Ne pas b E peur de plus de modèles, l'idée de OO est d'être en mesure de diviser vos préoccupations en petits morceaux et ensuite traiter chacun d'eux de la façon dont ils ont besoin d'être traités. Par exemple, votre modèle Property semble faire beaucoup de choses. Pourquoi ne pas séparer les informations géographiques que vous avez dans un EmbeddedDocument (lat, lng, adresse, etc)? De cette façon, votre code restera plus simple et plus lisible.

J'utilise moi-même ce type de STI et je trouve que mon code est beaucoup plus simple et plus utilisable. Une des beautés de l'utilisation d'une base de données comme Mongo est que vous pouvez faire des ITS très complexes comme celle-ci tout en ayant une collection de données gérable.

En ce qui concerne vos cuisine_types et beers_on_tap etc, je pense que ce sont de bons concepts. Il peut être utile d'avoir aussi des modèles Cuisine et Bière, donc votre base de données reste plus normalisée (un concept facile à perdre dans Mongo). par exemple:

class Bar < Property 
    key :beer_ids, Array 
    many :beers, :in => :beer_ids 
end 
class Beer 
    include MongoMapper:Document 
    key :name, String 
end 
+0

Merci pour la contribution, son très utile. Aussi, que pensez-vous des routes? Je voudrais utiliser le même contrôleur pour les propriétés et ses enfants, mais je ne suis pas sûr de savoir comment travailler en termes d'utilisation des routes ...c'est-à-dire que la route Restaurants similaires utilise toujours le contrôleur de propriété, mais des vues partielles spécifiques pour chaque sous-classe ... etc. Est-ce faisable? – holden

+0

Bien sûr, ce que je fais est (fondamentalement) convertir le nom de classe de l'instance spécifique en une chaîne et rendre ce partiel, en utilisant cette méthode d'assistance: (convertit TabContainerNode en tab_container) 'def partial_for (node) node.class. to_s.underscore.gsub (/ _ node $ /, "") end' Le gsub est optionnel bien sûr, je n'aime pas avoir _node sur tous mes partiels de nœuds. Alors vous avez le nom partiel et vous pouvez le rendre dans la vue: <% = render: partial => partial_for (node),: object => node%> – joshsz

+0

Mais, aussi comment puis-je utiliser un itinéraire comme/restaurants qui est une sous-classe de propriété, et transmettre cette information au contrôleur? map.resources: restaurants,: controller =>: properties fait marcher la route, mais je ne suis pas capable de savoir quelle URL les a amenés là pour afficher les restaurants et pas toutes les propriétés? – holden

0

Vous attendez-vous à retourner à la fois les restaurants et les bars dans la même requête?

Si ce n'est pas le cas, vous pouvez reconsidérer leur dérive d'un type de base.

Par défaut, Mongo_Mapper va placer à la fois les restaurants et les barres dans une seule collection. Cela pourrait entraver les performances et rendre les choses plus difficiles à l'échelle à l'avenir.

En parcourant certains codes Mongo_Mapper, il semblerait que vous puissiez définir ceci à la volée avec set_collection_name.