2010-03-19 4 views
1

Je ne suis pas sûr de la meilleure structure pour une situation particulière dans Rails. Nous avons plusieurs types d'ateliers. L'administration des ateliers est la même quel que soit le type d'atelier, de sorte que les données pour les ateliers sont dans un modèle unique. Nous collectons les retours des participants sur les ateliers, et le questionnaire est différent pour chaque type d'atelier. Je souhaite accéder aux commentaires sur l'atelier à partir du modèle d'atelier, mais la classe du modèle associé dépendra du type d'atelier. Si je faisais cela dans un autre domaine que Rails, je créerais une classe abstraite pour WorkshopFeedback, et j'aurais des sous-classes pour chaque type d'atelier: WorkshopFeedbackOne, WorkshopFeedbackTwo, WorkshopFeedbackThree. Je ne sais pas comment gérer cela au mieux avec Rails.plusieurs modèles dans Rails avec une interface partagée

J'ai actuellement:

class Workshop < ActiveRecord::Base 
    has_many :workshop_feedbacks 
end 

class Feedback < ActiveRecord::Base 
    belongs_to :workshop 
    has_many :feedback_ones 
    has_many :feedback_twos 
    has_many :feedback_threes 
end 

class FeedbackOne < ActiveRecord::Base 
    belongs_to :feedback 
end 

class FeedbackTwo < ActiveRecord::Base 
    belongs_to :feedback 
end 

class FeedbackThree < ActiveRecord::Base 
    belongs_to :feedback 
end 

Cela ne semble pas être la plus propre moyen d'accéder à la rétroaction du modèle d'atelier, comme l'accès à la rétroaction correcte nécessitera une logique d'instruction du type d'atelier, puis en choisissant, par exemple, @ workshop.feedback.feedback_one.

Y a-t-il une meilleure façon de gérer cette situation? Serait-il préférable d'utiliser une association polymorphe pour la rétroaction? Ou peut-être utiliser un module ou Mixin pour l'interface de feedback partagé? Remarque: J'évite d'utiliser l'héritage de table unique ici car les modèles FeedbackOne, FeedbackTwo, FeedbackThree ne partagent pas beaucoup de données communes, donc je finirais avec une grande table peu peuplée avec STI.

Répondre

1

Je pense que la meilleure solution est de créer un atelier de classe abstraite, et 3 sous-classes Atelier 1, atelier2 et Workshop3.

Ainsi, chacun aura son ensemble de rétroactions, à Feedback1 Atelier 1, Feedback2 à atelier2, ...

Vous pouvez modifier la déclaration dans les sous-classes comme suit:

class Workshop1 < Workshop 
    has_many :feedbacks, :class_name => "Feedback1" 
end 

class Feedback1 < ActiveRecord::Base 
    belongs_to :workshop, :class_name => "Workshop1" 
end 

Et dans votre L'application peut utiliser workshop.feedbacks et feedback.workshop, quelle que soit la classe de l'instance de l'atelier ou du feedback.

EDIT: Vous avez trois types d'atelier avec des informations en commun, mais chaque atelier dispose d'un type spécifique de commentaires. Il est donc préférable d'utiliser STI pour Workshop, et non pour Feedback.

0

Vous pouvez sous-classe vos modèles, comme ceci:

class Workshop < ActiveRecord::Base 
    has_many :feedback_ones 
    has_many :feedback_twos 
    has_many :feedback_threes 
    #has_many :feedbacks # This MIGHT work, but is untested. I'm not at a dev setup to try. 
end 

class Feedback < ActiveRecord::Base 
    belongs_to :workshop 
    has_many :feedback_ones 
    has_many :feedback_twos 
    has_many :feedback_threes 
end 

class FeedbackOne < Feedback 
    belongs_to :feedback 
end 

class FeedbackTwo < Feedback 
    belongs_to :feedback 
end 

class FeedbackThree < Feedback 
    belongs_to :feedback 
end 

Ceci est probablement une meilleure solution, et est plus propre. Votre table Feedback doit avoir une colonne type, qu'elle utilise pour utiliser une table pour plusieurs classes. This blog post donne une bonne introduction de base au concept de Single Table Inheritance.

+1

Je l'ai noté dans mon message original que je ne veux pas utiliser STI parce que les différentes évaluations ne partagent pas beaucoup de domaines, donc je finirais avec une grande table à faible densité de population. –

Questions connexes