2017-05-13 2 views
1

Je me suis gratté la tête sur ce problème de modélisation de données pendant quelques jours et j'ai décidé de vous demander de l'aide. Bien que je travaille avec Rails depuis plus de 7 ans, cette modélisation des relations m'échappe.Comment modéliser une relation Decision, Choice et ChoiceSet?

J'ai un modèle Decision, qui se compose essentiellement d'un attribut :question, par exemple:

Quelle équipe va gagner le Super Bowl cette année?

Pour chaque @decision, il existe un ensemble correspondant de @choices, par exemple:

  1. Dallas Cowboys
  2. New England Patriots
  3. Giants de New York
  4. Green Bay Packers

Je voudrais utiliser un modèle pour regrouper cet ensemble de @choices. Appelons cela un ChoiceSet.

Donc, pour résumer la relation souhaitée dans l'anglais:

Une décision a beaucoup de choix à travers un ChoiceSet.

Jusqu'ici, tout va bien. Voici où je suis confus. Normalement, on pourrait modéliser cette façon:

model Decision < ActiveRecord::Base 
    has_many :choice_sets 
    has_many :choices, through: :choice_sets 
end 

model Choice < ActiveRecord::Base 
    has_many :choice_sets 
    has_many :decisions, through: :choice_sets 
end 

model ChoiceSet < ActiveRecord::Base 
    belongs_to :decision 
    belongs_to :choice 
end 

Voici la mise en garde: La façon dont cela est modélisé, une décision pourrait avoir plusieurs ensembles de choix. Comment puis-je modéliser cela afin qu'une décision ne puisse avoir qu'un seul ensemble de choix?

Est-ce aussi simple que cela (en changeant simplement les has_many :choice_sets à has_one :choice_set?

model Decision < ActiveRecord::Base 
    has_one :choice_set 
    has_many :choices, through: :choice_set 
end 

model Choice < ActiveRecord::Base 
    has_many :choice_sets 
    has_many :decisions, through: :choice_sets 
end 

model ChoiceSet < ActiveRecord::Base 
    belongs_to :decision 
    belongs_to :choice 
end 

Merci pour votre aide.

Modifier

Comme surface par une réponse à cette question , Je devrais préciser que je voudrais éviter de dire qu'un Choice :belongs_to Decision de sorte que je n'ai pas besoin de créer un nouveau disque Choice n tout est pareil sauf le decision_id. Par exemple, je ne veux pas avoir 2 enregistrements Choice pour "Dallas Cowboys".

Répondre

1

Ok si nous disons que plusieurs décisions peuvent avoir le même ensemble de choix:

Quelle équipe va gagner le Super Bowl cette année?

et

Quelle équipe va venir en deuxième dans le Super Bowl cette année?

Nous savons qu'il ya un à plusieurs entre ChoiceSet et décision

Chaque ChoiceSet peut avoir beaucoup de choix, mais vous dites aussi que chaque choix peut appartenir à plusieurs ChoiceSets ... cela signifie que vous avez besoin une autre table de jointure. La relation serait quelque chose comme ...

model Decision < ActiveRecord::Base 
    belongs_to :choice_set 
    has_many :choices, through: :choice_set 
end 

model ChoiceSet < ActiveRecord::Base 
    has_many :decisions 
    has_many :choice_set_choice_links 
    has_many :choices, through: :choice_set_choice_links 
end 

model ChoiceSetChoiceLink < ActiveRecord::Base 
    belongs_to :choice_set 
    belongs_to :choice 

model Choice < ActiveRecord::Base 
    has_many choice_set_choice_links 
    has_many choice_sets, through: choice_set_choice_links 
    has_many :decisions, through: :choice_sets 
end 

La décision modèle a choice_set_id Le modèle ChoiceSetChoiceLink a choice_set_id et choice_id

+0

Le problème avec - et j'aurais indiqué dans ma première question - est que si un 'Choice' a' choice_set_id' alors je vais devoir générer des enregistrements de choix avec du contenu dupliqué (potentiellement) si j'ai un 'ChoiceSet' contenant, par exemple, 'Choice Foo', et un mois plus tard avoir un nouveau' ChoiceSet ' 'avec 'Choice Foo' ... Je voudrais éviter d'avoir des enregistrements' Choice' en double. – lightyrs

+1

Si vous voulez avoir une relation plusieurs-à-plusieurs, vous n'avez pas d'autre choix qu'une table de jointure. Si un Choice appartient à plusieurs ChoiceSets et qu'un ChoiceSet a de nombreux choix, vous avez besoin d'une table de jointure entre eux. Voir ma réponse éditée. – SteveTurczyn